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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14859458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:40:21  来源:igfitidea点击:

How to check if all values in the columns of a numpy matrix are the same?

pythonmatrixnumpy

提问by tobigue

I want to check if all values in the columns of a numpy array/matrix are the same. I tried to use reduceof the ufuncequal, but it doesn't seem to work in all cases:

我想检查一个 numpy 数组/矩阵的列中的所有值是否都相同。我试图用reduce的的ufuncequal,但它似乎不是在所有情况下工作时:

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)

Why does the middle column in the second case also evaluate to True, while it should be False?

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

Thanks for any help!

谢谢你的帮助!

采纳答案by unutbu

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

Compare each value to the corresponding value in the first row:

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

In [46]: a == a[0,:]
Out[46]: 
array([[ True,  True,  True],
       [ True, False,  True],
       [ True, False,  True],
       [ True,  True,  True]], dtype=bool)

A column shares a common value if all the values in that column are True:

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

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


The problem with np.equal.reducecan be seen by micro-analyzing what happens when it is applied to [1, 0, 0, 1]:

np.equal.reduce可以通过微观分析将其应用于 时发生的情况来看到的问题[1, 0, 0, 1]

In [49]: np.equal.reduce([1, 0, 0, 1])
Out[50]: True

The first two items, 1and 0are tested for equality and the result is False:

前两项,10被测试是否相等,结果是False

In [51]: np.equal.reduce([False, 0, 1])
Out[51]: True

Now Falseand 0are tested for equality and the result is True:

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

In [52]: np.equal.reduce([True, 1])
Out[52]: True

But Trueand 1 are equal, so the total result is True, which is not the desired outcome.

但是True和 1 是相等的,所以总结果是True,这不是想要的结果。

The problem is that reducetries to accumulate the result "locally", while we want a "global" test like np.all.

问题是reduce试图在“本地”累积结果,而我们想要一个“全局”测试,如np.all.

回答by Mad Physicist

Given ubuntu's awesome explanation, you can use reduceto solve your problem, but you have to apply it to bitwise_andand bitwise_orrather than equal. As a consequence, this will not work with floating point arrays:

鉴于 ubuntu 的出色解释,您可以使用它reduce来解决您的问题,但您必须将其应用于bitwise_andandbitwise_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)

Basically, you are comparing the bits of each element in the column. Identical bits are unchanged. Different bits are set to zero. This way, any number that has a zero instead of a one bit will change the reduced value. bitwise_andwill not trap the case where bits are introduced rather than removed:

基本上,您正在比较列中每个元素的位。相同的位不变。不同的位被设置为零。这样,任何具有零而不是一位的数字都会改变减少的值。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)

The second coumn is clearly wrong. We need to use bitwise_orto trap new bits:

第二个 coum 显然是错误的。我们需要使用bitwise_or来捕获新位:

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

Final Answer

最终答案

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)

This method is more restrictive and less elegant than ubunut's suggestion of using all, but it has the advantage of not creating enormous temporary arrays if your input is enormous. The temporary arrays should only be as big as the first row of your matrix.

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

EDIT

编辑

Based on this Q/Aand the bug I filed with numpy, the solution provided only works because your array contains zeros and ones. As it happens, the bitwise_and.reduce()operations shown can only ever return zero or one because bitwise_and.identityis 1, not -1. I am keeping this answer in the hope that numpygets fixed and the answer becomes valid.

基于这个Q/A我提交给 numpy 的错误,提供的解决方案仅有效,因为您的数组包含零和一。碰巧的是,显示的bitwise_and.reduce()操作只能返回零或一,因为bitwise_and.identity1,而不是-1。我保留这个答案,希望numpy得到修复并且答案变得有效。

Edit

编辑

Looks like there will in fact be a change to numpy soon. Certainly to bitwise_and.identity, and also possibly an optional parameter to reduce.

看起来实际上很快就会改变 numpy。当然 to bitwise_and.identity,也可能是一个可选参数来减少。

Edit

编辑

Good news everyone. The identity for np.bitwise_andhas been set to -1as of version 1.12.0.

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