Numpy:如何检查ndarray中的元组是否存在 [英] Numpy: How to check for tuples existence in ndarray
问题描述
使用numpy数组中的元组时,我发现了一个奇怪的行为.我想得到一个布尔值表,告诉我数组a
中的哪些元组也存在于数组b
中.通常,我会使用in
,in1d
中的任何一个.当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
.
我这样填充a
和b
:
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屋!