我有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(单元格2,1和2,3匹配所有3个矩阵)或[[False,False,False],[True,False,True]数组, [假,假,假]]?
答案 0 :(得分:4)
使用np.dstack
沿第三轴连接,并使用np.diff
进行分支,以便相同的那些显示为零。然后,检查所有都为~np.any
的零的情况。因此,您将拥有像这样的单线解决方案 -
~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)
答案 1 :(得分:3)
你可以这样做:
(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
参数的axis
函数是理想的,但没有一个,所以这一行注意到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)
)那么修改上述函数defs适当地并且添加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.
的列表,如果输入数组很大,那么快速接近大约4倍就是单独存储它们在列表中。我发现这有点令人惊讶,并猜测这可能是由于缓存交换(或错误的代码?),但我不确定是否有人真正关心所以我会在这里停止它。
答案 2 :(得分:1)
试试这个:
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) )