2

在使用 numpy 数组中的元组时,我发现了一个奇怪的行为。我想得到一个布尔值表,告诉我 array 中的哪些元组a也存在于 array 中b。通常,我会使用 , 中的任何in一个in1d。它们都不起作用,而tuple(a[1]) == b[1,1]yield 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)

谁能告诉我一个解决我的问题的方法,请告诉我为什么这不能按预期工作?

(顺便说一句,在这里使用 python2.7 和 numpy1.6.2。)

4

1 回答 1

5

为什么这不起作用

简短的版本是 numpy 的实现array.__contains__()似乎被破坏了。python 中的运算符在幕后in调用。__contains__()

意思a in b是等价于b.__contains__(a)

我已经在 REPL 中加载了您的数组并尝试以下操作:

>>> 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[:,:]是一个二维矩阵,所以它们当然是不相等的。但我假设您打算使用in而不是==. 如果我在这里错了,请纠正我,你的意思是我没有看到的不同的东西。

第一步是b从 2D 数组转换为 1D 数组,以便我们可以线性筛选它并将其转换为列表以避免 numpyarray.__contains()像这样损坏:

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

或者,更好的是,使它成为一个,set因为元组是不可变的,并且in在集合中检查是 O(1) 而不是列表的 O(n) 行为

>>> 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)])
>>> 

接下来我们简单地使用列表推导推导出布尔值表

>>> 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]
于 2013-02-24T23:35:32.437 回答