条件与平均numpy的
问题描述:
给定的2x3阵列,我要计算在axis=0
的平均水平,但只考虑那些值大于0条件与平均numpy的
所以给出的阵列
[ [1,0],
[0,0],
[1,0] ]
我想要的输出要
# 1, 0, 1 filtered for > 0 gives 1, 1, average = (1+1)/2 = 1
# 0, 0, 0 filtered for > 0 gives 0, 0, 0, average = 0
[1 0]
我当前的代码是
import numpy as np
frame = np.array([ [1,0],
[0,0],
[1,0] ])
weights=np.array(frame)>0
print("weights:")
print(weights)
print("average without weights:")
print((np.average(frame, axis=0)))
print("average with weights:")
print((np.average(frame, axis=0, weights=weights)))
这给了我
weights:
[[ True False]
[False False]
[ True False]]
average without weights:
[ 0.66666667 0. ]
average with weights:
Traceback (most recent call last):
File "C:\Users\myuser\project\test.py", line 123, in <module>
print((np.average(frame, axis=0, weights=weights)))
File "C:\Users\myuser\Miniconda3\envs\myenv\lib\site-packages\numpy\lib\function_base.py", line 1140, in average
"Weights sum to zero, can't be normalized")
ZeroDivisionError: Weights sum to zero, can't be normalized
我不明白这个错误。我在做什么错了,我怎么能得到沿axis=0
沿大于零的所有值的平均值?谢谢!
答
您可以获得大于零的掩码,并使用它沿第一个轴执行元素复用和减法。最后,除以沿着第一轴的屏蔽元素的数量以获得平均值。
因此,一个解决办法是 -
mask = a > 0 # Input array : a
out = np.einsum('i...,i...->...',a,mask)/mask.sum(0)
采样运行 -
In [52]: a
Out[52]:
array([[ 3, -3, 3],
[ 2, 2, 0],
[ 0, -3, 1],
[ 0, 1, 1]])
In [53]: mask = a > 0
In [56]: np.einsum('i...,i...->...',a,mask) # summations of > 0s
Out[56]: array([5, 3, 5])
In [57]: np.einsum('i...,i...->...',a,mask)/mask.sum(0) # avg values of >0s
Out[57]: array([ 2.5 , 1.5 , 1.66666667])
要占全部零列,看来我们期待0
作为结果。所以,我们可以用np.where
做选择,就像这样 -
In [61]: a[:,-1] = 0
In [62]: a
Out[62]:
array([[ 3, -3, 0],
[ 2, 2, 0],
[ 0, -3, 0],
[ 0, 1, 0]])
In [63]: mask = a > 0
In [65]: np.where(mask.any(0), np.einsum('i...,i...->...',a,mask)/mask.sum(0), 0)
__main__:1: RuntimeWarning: invalid value encountered in true_divide
Out[65]: array([ 2.5, 1.5, 0. ])
只是忽略警告那里。
如果你觉得偏执的警告,使用masking
-
mask = a > 0
vm = mask.any(0) # valid mask
out = np.zeros(a.shape[1])
out[vm] = np.einsum('ij,ij->j',a[:,vm],mask[:,vm])/mask.sum(0)[vm]
+0
当然,在没有积极因素的情况下,你仍然被零分,所以如果发生这种情况,你会得到一个平均值。尝试取平均数字的概念性问题仍然存在。 – user2357112
+0
@ user2357112好点!编辑涵盖这种情况。 – Divakar
'0,0,0过滤为> 0产生0,0,0' ......不,它不需要。你能否更准确地描述你如何处理没有找到积极因素的情况?结果应该总是0吗?结果应该是所有元素的平均值吗?是否应该计算一些其他的价值? – user2357112
加权平均值计算为平均数和权重的乘积之和除以权重之和。由于第二列的权重加起来为0(所有三个都是“假”),所以这种划分是不可能的。 – DyZ
和对发布的解决方案的反馈? – Divakar