Python中的matlab ismember函数

3 投票
4 回答
21027 浏览
提问于 2025-04-22 12:33

虽然之前有类似的问题被提过几次,但我还是没法在Python里写出一个和matlab的ismember函数类似的功能。具体来说,我想在一个循环里使用这个函数,每次迭代时把一个完整的矩阵和另一个矩阵的一个元素进行比较。只要有相同的值出现,我想打印1,其他情况下打印0。

假设我有以下这些矩阵:

d = np.reshape(np.array([ 2.25,  1.25,  1.5 ,  1.  ,  0.  ,  1.25,  1.75,  0.  ,  1.5 ,  0.  ]),(1,10))
d_unique = np.unique(d)

然后我有:

d_unique
array([ 0.  ,  1.  ,  1.25,  1.5 ,  1.75,  2.25])

现在我想像这样进行迭代:

J = np.zeros(np.size(d_unique))
for i in xrange(len(d_unique)):
        J[i] = np.sum(ismember(d,d_unique[i]))

这样输出的结果应该是:

J = [3,1,2,2,1,1]

有没有人有好的主意?非常感谢!

暂无标签

4 个回答

0

可以试试从pypi上下载的 ismember 库。

pip install ismember

举个例子:

# Import library
from ismember import ismember

# data
d = [ 2.25,  1.25,  1.5 ,  1.  ,  0.  ,  1.25,  1.75,  0.  ,  1.5 ,  0.  ]
d_unique = [ 0.  ,  1.  ,  1.25,  1.5 ,  1.75,  2.25]

# Lookup
Iloc,idx = ismember(d, d_unique)
 
# Iloc is boolean defining existence of d in d_unique
print(Iloc)
# [[True  True  True  True  True  True  True  True  True  True]]

# indexes of d_unique that exists in d
print(idx)
# array([5, 2, 3, 1, 0, 2, 4, 0, 3, 0], dtype=int64)

print(d_unique[idx])
array([2.25, 1.25, 1.5 , 1.  , 0.  , 1.25, 1.75, 0.  , 1.5 , 0.  ])

print(d[Iloc])
array([2.25, 1.25, 1.5 , 1.  , 0.  , 1.25, 1.75, 0.  , 1.5 , 0.  ])

# These vectors will match
d[Iloc]==d_unique[idx]
2

为了回答你的问题,我想你可以这样定义一个叫做“ismember”的东西:

def ismember(d, k):
  return [1 if (i == k) else 0 for i in d]

不过我对numpy不太熟悉,所以可能需要稍微调整一下。

我想你也可以使用collections里的Counter:

>>> from collections import Counter
>>> a = [2.25,  1.25,  1.5,  1.,  0.,  1.25,  1.75,  0.,  1.5,  0. ]
>>> Counter(a)
Counter({0.0: 3, 1.25: 2, 1.5: 2, 2.25: 1, 1.0: 1, 1.75: 1})
>>> Counter(a).keys()
[2.25, 1.25, 0.0, 1.0, 1.5, 1.75]
>>> c =Counter(a)
>>> [c[i] for i in sorted(c.keys())]
[3, 1, 2, 2, 1, 1]

再说一次,我不是很懂numpy,你可能需要在某个地方用到 list(d)

15

跟其他回答相比,numpy 有一个内置的功能叫做 numpy.in1d,可以用来完成这个任务。

在你的情况下的用法是:

bool_array = numpy.in1d(array1, array2)

注意:它也可以接受列表作为输入。

编辑(2021):现在 numpy 推荐使用 np.isin 来替代 np.in1dnp.isin 可以保持输入数组的形状,而 np.in1d 返回的是扁平化的输出。

1

试试下面这个函数:

def ismember(A, B):
    return [ np.sum(a == B) for a in A ]

这个函数的表现应该和相应的MATLAB函数非常相似。

撰写回答