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)
前两项,1
并0
进行相等测试,结果如下False
:
In [51]: np.equal.reduce([False, 0, 1])
Out[51]: True
Run Code Online (Sandbox Code Playgroud)
现在False
和0
测试是否相等,结果是True
:
In [52]: np.equal.reduce([True, 1])
Out[52]: True
Run Code Online (Sandbox Code Playgroud)
但是True
1和1是相等的,所以总结果是True
,这不是理想的结果.
问题是reduce
尝试"本地"积累结果,而我们想要一个"全局"测试np.all
.
鉴于Ubuntu的真棒解释,您可以使用reduce
来解决你的问题,但你必须运用它来bitwise_and
和bitwise_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.identity
是1
,没有-1
.我保留这个答案,希望numpy
得到修复,答案变得有效.
编辑
看起来事实上很快就会变成numpy.当然bitwise_and.identity
,也可能是减少的可选参数.
编辑
大家好消息.标识np.bitwise_and
已设置-1
为版本1.12.0
.
归档时间: |
|
查看次数: |
39067 次 |
最近记录: |