这是我的问题:我想创建一个布尔矩阵B,其中包含True
,矩阵A的值包含在向量v中。一个不方便的解决方案是:
import numpy as np
>>> A = np.array([[0,1,2], [1,2,3], [2,3,4]])
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])
>>> v = [1,2]
>>> B = (A==v[0]) + (A==v[1]) # matlab: ``B = ismember(A,v)``
array([[False, True, True],
[ True, True, False],
[ True, False, False]], dtype=bool)
如果A和v有更多值,是否有更方便的解决方案?
干杯!
答案 0 :(得分:4)
我不知道多少numpy,在这里是一个原始的蟒蛇:
>>> A = [[0,1,2], [1,2,3], [2,3,4]]
>>> v = [1,2]
>>> B = [map(lambda val: val in v, a) for a in A]
>>>
>>> B
[[False, True, True], [True, True, False], [True, False, False]]
编辑:正如Brooks Moses指出的那样,一些简单的时机似乎表明,这个可能会更好:
>>> B = [ [val in v for val in a] for a in A]
答案 1 :(得分:3)
使用numpy原语:
>>> import numpy as np
>>> A = np.array([[0,1,2], [1,2,3], [2,3,4]])
>>> v = [1,2]
>>> print np.vectorize(lambda x: x in v)(A)
[[False True True]
[ True True False]
[ True False False]]
对于非微小输入,将v转换为先设置为大加速。
使用numpy.setmember1d:
Auniq, Ainv = np.unique1d(A, return_inverse=True)
result = np.take(np.setmember1d(Auniq, np.unique1d(v)), Ainv).reshape(A.shape)
答案 2 :(得分:3)
唉,当任何一个数组都有重复元素时,numpy中存在的setmember1d
就会被破坏(如A所做)。下载this版本,在sys.path的某个地方调用它,例如sem.py,添加第一行import numpy as nm
,然后这最终有效:
>>> import sem
>>> print sem.setmember1d(A.reshape(A.size), v).reshape(A.shape)
[[False True True]
[True True False]
[True False False]]
注意差异与@Aants'类似的答案:这个版本的结果bool数组的第二行是正确的,而他的版本(使用作为numpy的一部分的setmember1d
)错误地将第二行作为所有True
s。
答案 3 :(得分:2)
自Numpy 1.4版以来,有一个新函数in1d(),它相当于matlab中的ismember():http://docs.scipy.org/doc/numpy-1.6.0/reference/generated/numpy.in1d.html。但是,正如ars指出的那样,它只返回一个1d数组。
答案 4 :(得分:1)
这是一个天真的单行:
[any (value in item for value in v) for item in A]
示例输出:
>>> A = ( [0,1,2], [1,2,3], [2,3,4] )
>>> v = [1,2]
>>> [any (value in item for value in v) for item in A]
[True, True, True]
>>> v = [1]
>>> [any (value in item for value in v) for item in A]
[True, True, False]
这是一种非常Pythonic的方法,但我确信它不会在大型数组或向量上很好地扩展,因为Python的in
运算符是线性搜索(至少在列表/元组上)。
正如Brooks Moses在下面的评论中指出的那样,输出应该是3x3矩阵。这就是你在问题中提供样本输出的原因。 (谢谢布鲁克斯)
>>> v=[1,2]
>>> [ [item in v for item in row] for row in A]
[[False, True, True], [True, True, False], [True, False, False]]
>>> v=[1]
>>> [ [item in v for item in row] for row in A]
[[False, True, False], [True, False, False], [False, False, False]]
答案 5 :(得分:1)
我认为你得到的最接近的是numpy.ismember1d
,但它不适用于你的例子。我认为你的解决方案(B = (A==v[0]) + (A==v[1])
)实际上可能是最好的解决方案。