Python:相同形状数组的元素级比较
我有n个大小相同的矩阵,我想看看所有矩阵中有多少个单元彼此相等。代码:Python:相同形状数组的元素级比较,python,numpy,Python,Numpy,我有n个大小相同的矩阵,我想看看所有矩阵中有多少个单元彼此相等。代码: import numpy as np a = np.array([[1,2,3],[4,5,6],[7,8,9]]) b = np.array([[5,6,7], [4,2,6], [7, 8, 9]]) c = np.array([2,3,4],[4,5,6],[1,2,5]) #Intuition is below but is wrong a == b == c 如何让Python返回2的值(所有3个矩阵中的单元格
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.array([[5,6,7], [4,2,6], [7, 8, 9]])
c = np.array([2,3,4],[4,5,6],[1,2,5])
#Intuition is below but is wrong
a == b == c
如何让Python返回2的值(所有3个矩阵中的单元格2,1和2,3都匹配)或[[False,False,False]、[True,False,True]、[False,False]]的数组?您可以执行以下操作:
(a == b) & (b==c)
[[False False False]
[ True False True]
[False False False]]
对于n
项,例如,类似x=[a,b,c,a,b,c]
的列表,可以执行以下操作:
r = x[0] == x[1]
for temp in x[2:]:
r &= x[0]==temp
结果现在显示在r
中
如果结构已在3D numpy阵列中,还可以使用:
np.amax(x,axis=2)==np.amin(x,axis=2)
上面这一行的想法是,虽然理想的做法是使用带有轴
参数的equal
函数,但没有这样的函数,因此这一行注意到,如果amin==amax
沿着轴,那么所有元素都是相等的
如果要比较的不同阵列尚未在3D numpy阵列中(或将来不会),则循环列表是一种快速而简单的方法。虽然我通常同意避免为Numpy数组使用Python循环,但在这种情况下,使用Python循环似乎更容易、更快(见下文),因为循环只沿着一个轴,并且比较容易累积到位。下面是一个计时测试:
def f0(x):
r = x[0] == x[1]
for y in x[2:]:
r &= x[0]==y
def f1(x): # from @Divakar
r = ~np.any(np.diff(np.dstack(x),axis=2),axis=2)
def f2(x):
x = np.dstack(x)
r = np.amax(x,axis=2)==np.amin(x,axis=2)
# speed test
for n, size, reps in ((1000, 3, 1000), (10, 1000, 100)):
x = [np.ones((size, size)) for i in range(n)]
print n, size, reps
print "f0: ",
print timeit("f0(x)", "from __main__ import x, f0, f1", number=reps)
print "f1: ",
print timeit("f1(x)", "from __main__ import x, f0, f1", number=reps)
print
1000 3 1000
f0: 1.14673900604 # loop
f1: 3.93413209915 # diff
f2: 3.93126702309 # min max
10 1000 100
f0: 2.42633581161 # loop
f1: 27.1066679955 # diff
f2: 25.9518558979 # min max
如果阵列已经在单个3D numpy阵列中(例如,在上面使用x=np.dstack(x)
),则适当修改上述函数def,并添加min==max
方法,可得出:
def g0(x):
r = x[:,:,0] == x[:,:,1]
for iy in range(x[:,:,2:].shape[2]):
r &= x[:,:,0]==x[:,:,iy]
def g1(x): # from @Divakar
r = ~np.any(np.diff(x,axis=2),axis=2)
def g2(x):
r = np.amax(x,axis=2)==np.amin(x,axis=2)
这将产生:
1000 3 1000
g0: 3.9761030674 # loop
g1: 0.0599548816681 # diff
g2: 0.0313589572906 # min max
10 1000 100
g0: 10.7617051601 # loop
g1: 10.881870985 # diff
g2: 9.66712999344 # min max
还要注意的是,对于大型数组的列表,f0=2.4和预构建数组,g0、g1、g2~=10.,因此,如果输入数组很大,则最快的方法是将它们分别存储在一个列表中。我觉得这有点奇怪,并猜测这可能是由于缓存交换(或错误的代码?),但我不确定是否有人真的在乎,因此我将在这里停止此操作。尝试以下方法:
z1 = a == b
z2 = a == c
z = np.logical_and(z1,z2)
print "count:", np.sum(z)
您可以在一条语句中执行此操作:
count = np.sum( np.logical_and(a == b, a == c) )
沿第三个轴连接和执行微分,以便相同的显示为零。然后,检查所有为零的情况。因此,您将有一个这样的一行解决方案-
~np.any(np.diff(np.dstack((a,b,c)),axis=2),axis=2)
样本运行-
In [39]: a
Out[39]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [40]: b
Out[40]:
array([[5, 6, 7],
[4, 2, 6],
[7, 8, 9]])
In [41]: c
Out[41]:
array([[2, 3, 4],
[4, 5, 6],
[1, 2, 5]])
In [42]: ~np.any(np.diff(np.dstack((a,b,c)),axis=2),axis=2)
Out[42]:
array([[False, False, False],
[ True, False, True],
[False, False, False]], dtype=bool)
有一个普遍的答案吗?如果我有3个以上的矩阵,那么得出答案所需的组合和步骤将爆炸。@user1842834:我还应该注意,“组合”不会爆炸。没有组合和爆炸,这只是O(n)。将其视为一个单元素数组,例如数字
5
。然后你有一个数字列表,然后你沿着列表询问每个元素是否等于5
。这只是一个矩阵。没有必要对每个元素进行比较。