Python 检查不同numpy数组中是否有相同的行
如何在行真/假数组的结果中获得两个数组之间的行比较 给定数据:Python 检查不同numpy数组中是否有相同的行,python,arrays,numpy,Python,Arrays,Numpy,如何在行真/假数组的结果中获得两个数组之间的行比较 给定数据: a = np.array([[1,0],[2,0],[3,1],[4,2]]) b = np.array([[1,0],[2,0],[4,2]]) 结果步骤1: c = np.array([True, True,False,True]) 最终结果: a = a[c] 那么如何获得数组c 注意:在本例中,数组a和b已排序,如果在您的解决方案中数组排序很重要,请提供相关信息。您可以通过以下方式将其作为列表进行排序: c = np.
a = np.array([[1,0],[2,0],[3,1],[4,2]])
b = np.array([[1,0],[2,0],[4,2]])
结果步骤1:
c = np.array([True, True,False,True])
最终结果:
a = a[c]
那么如何获得数组c
注意:在本例中,数组
a
和b
已排序,如果在您的解决方案中数组排序很重要,请提供相关信息。您可以通过以下方式将其作为列表进行排序:
c = np.array([row in b for row in a])
尽管这种方法比纯numpy方法(如果存在的话)要慢。您可以使用numpy并沿_轴应用_(在特定轴上的一种迭代,axis=0在每个单元格上迭代,axis=1在每行上迭代,axis=2在矩阵上迭代,依此类推
import numpy as np
a = np.array([[1,0],[2,0],[3,1],[4,2]])
b = np.array([[1,0],[2,0],[4,2]])
c = np.apply_along_axis(lambda x,y: x in y, 1, a, b)
我们可以利用它们被排序的事实,在O(n)时间内完成这项工作。使用两个指针,我们只需向前移动已经落后的指针:
while i < len(a) and j < len(b):
if tuple(a[i])== tuple(b[j]):
result.append(True)
i += 1
j += 1 # get rid of this depending on how you want to handle duplicates
elif tuple(a[i]) > tuple(b[j]):
j += 1
else:
result.append(False)
i += 1
当ituple(b[j]):
j+=1
其他:
result.append(False)
i+=1
如果它提前结束,则用False填充
if len(result) < len(a):
result.extend([False] * (len(a) - len(result)))
print(result) # [True, True, False, True]
如果len(结果)
此答案改编自以下矢量化解决方案:
res = (a[:, None] == b).all(-1).any(-1)
print(res)
array([ True, True, False, True])
请注意,a[:,None]==b
将a
的每一行与b
元素进行比较。然后,我们使用all
+any
来推断每个子数组中是否有所有为真的行:
print(a[:, None] == b)
[[[ True True]
[False True]
[False False]]
[[False True]
[ True True]
[False False]]
[[False False]
[False False]
[False False]]
[[False False]
[False False]
[ True True]]]
方法#1
我们可以使用基于视图的矢量化解决方案-
# https://stackoverflow.com/a/45313353/ @Divakar
def view1D(a, b): # a, b are arrays
a = np.ascontiguousarray(a)
b = np.ascontiguousarray(b)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel(), b.view(void_dt).ravel()
A,B = view1D(a,b)
out = np.isin(A,B)
样本运行-
In [8]: a
Out[8]:
array([[1, 0],
[2, 0],
[3, 1],
[4, 2]])
In [9]: b
Out[9]:
array([[1, 0],
[2, 0],
[4, 2]])
In [10]: A,B = view1D(a,b)
In [11]: np.isin(A,B)
Out[11]: array([ True, True, False, True])
方法#2
或者,如果b
中的所有行都在a
中,并且行是按字典顺序排序的,则使用相同的视图
,但使用搜索排序
-
out = np.zeros(len(A), dtype=bool)
out[np.searchsorted(A,B)] = 1
如果行不一定按字典顺序排序-
sidx = A.argsort()
out[sidx[np.searchsorted(A,B,sorter=sidx)]] = 1
您可以使用scipy的cdist,它有几个优点:
from scipy.spatial.distance import cdist
a = np.array([[1,0],[2,0],[3,1],[4,2]])
b = np.array([[1,0],[2,0],[4,2]])
c = cdist(a, b)==0
print(c.any(axis=1))
此外,cdist允许传递函数指针。因此,您可以指定自己的距离函数,以进行所需的任何比较:
c = cdist(a, b, lambda u, v: (u==v).all())
print(c)
现在您可以找到与之匹配的索引。这也将指示是否有多个匹配
# Array with multiple instances
a2 = np.array([[1,0],[2,0],[3,1],[4,2],[3,1],[4,2]])
c2 = cdist(a2, b, lambda u, v: (u==v).all())
print(c2)
idx = np.where(c2==1)
print(idx)
print(idx[0][idx[1]==2])
这实际上没有使用np.isin
,有点困惑你为什么提到它,因为我认为它在这里不是特别有用。似乎不起作用,以便检查相同的行:a=np.array([[1,0],[2,0],[4,2],[3,1],[3,0]])b=np array([[1,0],[2,0],[3,1]])c=np c最后一个应该是False这看起来不错a=np数组([[1,0],[2,0],[4,2],[3,1],[3,0]])b=np数组([[1,0],[2,0],[3,1]])c=(a[:,None]==b.all(-1).any(-1)结果[真假]谢谢,这是我见过的最简单的方法!类似于这里的方法#1有效,第二种方法到目前为止尚未测试(或理解)…谢谢
print(a[c.any(axis=1)])
[[1 0]
[2 0]
[4 2]]
c = cdist(a, b, lambda u, v: (u==v).all())
print(c)
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 0.]
[0. 0. 1.]]
# Array with multiple instances
a2 = np.array([[1,0],[2,0],[3,1],[4,2],[3,1],[4,2]])
c2 = cdist(a2, b, lambda u, v: (u==v).all())
print(c2)
idx = np.where(c2==1)
print(idx)
print(idx[0][idx[1]==2])
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 0.]
[0. 0. 1.]
[0. 0. 0.]
[0. 0. 1.]]
(array([0, 1, 3, 5], dtype=int64), array([0, 1, 2, 2], dtype=int64))
[3 5]