我有从哪个列表中得到非零值的平均值。计算非零值的平均值
E.G
[2,2,0,0,0] -> 2
[1,1,0,1,0] -> 1
[0,0,0,9,0] -> 9
[2,3,0,0,0] -> 2.5
现在我这样做:
list_ = [1,1,0,1,0]
non_zero = [float(v) for v in list_ if v>0]
averge = sum(non_zero)/len(non_zero)
我怎样才能做到这一点的操作更有效率?
我有从哪个列表中得到非零值的平均值。计算非零值的平均值
E.G
[2,2,0,0,0] -> 2
[1,1,0,1,0] -> 1
[0,0,0,9,0] -> 9
[2,3,0,0,0] -> 2.5
现在我这样做:
list_ = [1,1,0,1,0]
non_zero = [float(v) for v in list_ if v>0]
averge = sum(non_zero)/len(non_zero)
我怎样才能做到这一点的操作更有效率?
如果你以一个numpy的数组,你可以使用np.nonzero
到滤镜阵列,然后取平均值:
a = np.array([2,3,0,0,0])
average = a[np.nonzero(a)].mean()
您还可以通过布尔检索,这似乎是更快的过滤:
average = a[a!=0].mean()
您也可以通过使用a>0
轻松更改上述方法以筛选正值。
时序
使用以下设置:
a = np.random.randint(100, size=10**6)
我得到以下计时:
%timeit a[a!=0].mean()
100 loops, best of 3: 4.59 ms per loop
%timeit a[a.nonzero()].mean()
100 loops, best of 3: 9.82 ms per loop
你可以使用np.nonzero
:
l = np.array([2,2,0,0,0])
l[l.nonzero()].mean()
Out[17]: 2.0
一个粗略的基准包裹你目前的做法,这在一个功能:
def luis_way(l):
non_zero = [float(v) for v in l if v>0]
average = sum(non_zero)/len(non_zero)
return average
def np_way(l):
return l[l.nonzero()].mean()
In [19]: some_l = np.random.randint(2, size=10000)
In [20]: %timeit luis_way(some_l)
100 loops, best of 3: 4.72 ms per loop
In [21]: %timeit np_way(some_l)
1000 loops, best of 3: 262 µs per loop
对于小的投入,但是,你目前的做法可能是罚款。 然而值得注意的是,你现在的答案并不是实际采用所有非零元素,而只是积极因素。
嘿,我只使用正数。但是,感谢这面旗帜,我没有注意到它。 –
这里是与转换列表的列表为2D
阵列后总结一个量化的方法 -
from __future__ import division
a = np.asarray(list_)
a.sum(1)/(a!=0).sum(1)
采样运行 - !
In [32]: list_ # Input list of lists
Out[32]: [[2, 2, 0, 0, 0], [1, 1, 0, 1, 0], [0, 0, 0, 9, 0], [2, 3, 0, 0, 0]]
In [33]: a = np.asarray(list_) # Convert to array
In [34]: a.sum(1)/(a!=0).sum(1) # Divide row sums by count of non-zeros
Out[34]: array([ 2. , 1. , 9. , 2.5])
非零值意味着'V = 0'。在你的情况下,'v> 0'意味着正数 –
你不把输入作为列表的列表,如:[[[2,2,0,0,0],[1,1,0。 ...]]'或者它是一个数组? – Divakar