如何检查numpy矩阵列中的所有值是否相同?

tob*_*gue 28 python numpy matrix

我想检查numpy数组/矩阵的列中的所有值是否相同.我试图用reduce的的ufunc equal,但它似乎并没有在所有情况下的工作:

In [55]: a = np.array([[1,1,0],[1,-1,0],[1,0,0],[1,1,0]])

In [56]: a
Out[56]: 
array([[ 1,  1,  0],
       [ 1, -1,  0],
       [ 1,  0,  0],
       [ 1,  1,  0]])

In [57]: np.equal.reduce(a)
Out[57]: array([ True, False,  True], dtype=bool)

In [58]: a = np.array([[1,1,0],[1,0,0],[1,0,0],[1,1,0]])

In [59]: a
Out[59]: 
array([[1, 1, 0],
       [1, 0, 0],
       [1, 0, 0],
       [1, 1, 0]])

In [60]: np.equal.reduce(a)
Out[60]: array([ True,  True,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

为什么第二种情况下的中间列也要评估True,而它应该是False

谢谢你的帮助!

unu*_*tbu 46

In [45]: a
Out[45]: 
array([[1, 1, 0],
       [1, 0, 0],
       [1, 0, 0],
       [1, 1, 0]])
Run Code Online (Sandbox Code Playgroud)

将每个值与第一行中的相应值进行比较:

In [46]: a == a[0,:]
Out[46]: 
array([[ True,  True,  True],
       [ True, False,  True],
       [ True, False,  True],
       [ True,  True,  True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

如果该列中的所有值都为True,则列共享一个公共值:

In [47]: np.all(a == a[0,:], axis = 0)
Out[47]: array([ True, False,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

np.equal.reduce通过微观分析可以看出问题,当它应用于[1, 0, 0, 1]:

In [49]: np.equal.reduce([1, 0, 0, 1])
Out[50]: True
Run Code Online (Sandbox Code Playgroud)

前两项,10进行相等测试,结果如下False:

In [51]: np.equal.reduce([False, 0, 1])
Out[51]: True
Run Code Online (Sandbox Code Playgroud)

现在False0测试是否相等,结果是True:

In [52]: np.equal.reduce([True, 1])
Out[52]: True
Run Code Online (Sandbox Code Playgroud)

但是True1和1是相等的,所以总结果是True,这不是理想的结果.

问题是reduce尝试"本地"积累结果,而我们想要一个"全局"测试np.all.


Mad*_*ist 8

鉴于Ubuntu的真棒解释,您可以使用reduce来解决你的问题,但你必须运用它来bitwise_andbitwise_or,而不是equal.因此,这不适用于浮点数组:

In [60]: np.bitwise_and.reduce(a) == a[0]
Out[60]: array([ True, False,  True], dtype=bool)

In [61]: np.bitwise_and.reduce(b) == b[0]
Out[61]: array([ True, False,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

基本上,您要比较列中每个元素的位.相同的位不变.不同的位设置为零.这样,任何具有零而不是一位的数字都将改变减小的值.bitwise_and不会陷入引入而不是删除位的情况:

In [62]: c = np.array([[1,0,0],[1,0,0],[1,0,0],[1,1,0]])

In [63]: c
Out[63]: 
array([[1, 0, 0],
       [1, 0, 0],
       [1, 0, 0],
       [1, 1, 0]])

In [64]: np.bitwise_and.reduce(c) == c[0]
Out[64]: array([ True,  True,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

第二个结果显然是错误的.我们需要用来bitwise_or捕获新位:

In [66]: np.bitwise_or.reduce(c) == c[0]
Out[66]: array([ True, False,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

最终答案

In [69]: np.logical_and(np.bitwise_or.reduce(a) == a[0], np.bitwise_and.reduce(a) == a[0])
Out[69]: array([ True, False,  True], dtype=bool)

In [70]: np.logical_and(np.bitwise_or.reduce(b) == b[0], np.bitwise_and.reduce(b) == b[0])
Out[70]: array([ True, False,  True], dtype=boo

In [71]: np.logical_and(np.bitwise_or.reduce(c) == c[0], np.bitwise_and.reduce(c) == c[0])
Out[71]: array([ True, False,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

这种方法比ubunut的使用建议更具限制性和优雅性all,但如果您的输入很大,它的优点是不会创建巨大的临时数组.临时数组应该只与矩阵的第一行一样大.

编辑

基于此Q/A以及我提交numpy的错误,提供的解决方案仅适用,因为您的数组包含零和1.当它发生时,bitwise_and.reduce()显示操作永远只能返回零个或一个原因bitwise_and.identity1,没有-1.我保留这个答案,希望numpy得到修复,答案变得有效.

编辑

看起来事实上很快就会变成numpy.当然bitwise_and.identity,也可能是减少的可选参数.

编辑

大家好消息.标识np.bitwise_and已设置-1为版本1.12.0.