Numpy:如何检查ndarray中的元组是否存在 [英] Numpy: How to check for tuples existence in ndarray

查看:363
本文介绍了Numpy:如何检查ndarray中的元组是否存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用numpy数组中的元组时,我发现了一个奇怪的行为.我想得到一个布尔值表,告诉我数组a中的哪些元组也存在于数组b中.通常,我会使用inin1d中的任何一个.当tuple(a[1]) == b[1,1]产生True时,它们都不起作用.

I found a strange behavior when working with tuples in numpy arrays. I want to get a table of booleans telling me which tuples in array a also exist in array b. Normally, I would use any of in, in1d. None of them work while tuple(a[1]) == b[1,1] yields True.

我这样填充ab:

a = numpy.array([(0,0)(1,1)(2,2)], dtype=tuple)

b = numpy.zeros((3,3), dtype=tuple)
for i in range(0,3):
    for j in range(0,3):
        b[i,j] = (i,j)

任何人都可以告诉我解决我的问题的方法,并请启发我为什么这不能按预期进行吗?

Can anyone tell me a solution to my problem and please enlighten me why this does not work as expected?

(在这里顺便使用python2.7和numpy1.6.2.)

(Using python2.7 and numpy1.6.2 over here btw.)

推荐答案

为什么这不起作用

简短的版本是numpy的array.__contains__()实现似乎已损坏. python中的in运算符在后台调用__contains__().

The short version is that numpy's implementation of array.__contains__() seems to be broken. The in operator in python calls __contains__() behind the scenes.

表示a in b等同于b.__contains__(a).

我已将您的阵列加载到REPL中,然后尝试以下操作:

I've loaded up your arrays in a REPL and try the following:

>>> b[:,0]
array([(0, 0), (1, 0), (2, 0)], dtype=object)
>>> (0,0) in b[:,0] # we expect it to be true
False
>>> (0,0) in list(b[:,0]) # this shouldn't be different from the above but it is
True
>>> 

如何修复

由于a[x]是一个元组而b[:,:]是一个2D矩阵,所以我看不到您的列表理解如何工作,所以它们当然不相等.但是我假设您打算使用in而不是==.如果我错了,请纠正我,而您的意思是我没看到的不一样.

I don't see how your list comprehension could work since a[x] is a tuple and b[:,:] is a 2D matrix so of course they're not equal. But I'm assuming you meant to use in instead of ==. Do correct me if I'm wrong here and you meant something different that I'm just not seeing.

第一步是将b从2D数组转换为1D数组,以便我们可以对其进行线性筛选并将其转换为列表,以避免numpy损坏array.__contains(),如下所示:

The first step is to convert b from a 2D array to a 1D array so we can sift through it linearly and convert it to a list to avoid numpy's broken array.__contains() like so:

bb = list(b.reshape(b.size))

或者更好的是,将其设为set,因为元组是不可变的,并且检查集合中的in是O(1)而不是列表的O(n)行为

Or, better yet, make it a set since tuples are immutable and checking for in in a set is O(1) instead of the list's O(n) behavior

>>> bb = set(b.reshape(b.size))
>>> print bb
set([(0, 1), (1, 2), (0, 0), (2, 1), (1, 1), (2, 0), (2, 2), (1, 0), (0, 2)])
>>> 

接下来,我们仅使用列表推导来导出布尔值表

Next we simply use the list comprehension to derive the table of booleans

>>> truth_table = [tuple(aa) in bb for aa in a]
>>> print truth_table
[True, True, True]
>>> 

完整代码:

def contained(a,b):
    bb = set(b.flatten())
    return [tuple(aa) in bb for aa in a]

这篇关于Numpy:如何检查ndarray中的元组是否存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆