假设我有以下列表列表:
a = [
[1, 2, 3],
[2, 3, 4],
[3, 4, 5, 6]
]
我想获得数组中每个第n个元素的平均值。但是,当想要以一种简单的方式执行此操作时,由于长度不同,Python会生成越界错误。我通过为每个数组指定最长数组的长度并用None填充缺失值来解决此问题。
不幸的是,这样做使无法计算平均值,因此我将阵列转换为蒙版阵列。下面显示的代码有效,但是看起来很麻烦。
import numpy as np
import numpy.ma as ma
a = [ [1, 2, 3],
[2, 3, 4],
[3, 4, 5, 6] ]
# Determine the length of the longest list
lenlist = []
for i in a:
lenlist.append(len(i))
max = np.amax(lenlist)
# Fill each list up with None's until required length is reached
for i in a:
if len(i) <= max:
for j in range(max - len(i)):
i.append(None)
# Fill temp_array up with the n-th element
# and add it to temp_array
temp_list = []
masked_arrays = []
for j in range(max):
for i in range(len(a)):
temp_list.append(a[i][j])
masked_arrays.append(ma.masked_values(temp_list, None))
del temp_list[:]
# Compute the average of each array
avg_array = []
for i in masked_arrays:
avg_array.append(np.ma.average(i))
print avg_array
有办法更快地做到这一点吗?列表的最终列表将包含600000个“行”和最多100个“列”,因此效率非常重要:-)。
tertools.izip_longest将为您完成所有的None操作,因此您的代码可以简化为:
import numpy as np
import numpy.ma as ma
from itertools import izip_longest
a = [ [1, 2, 3],
[2, 3, 4],
[3, 4, 5, 6] ]
averages = [np.ma.average(ma.masked_values(temp_list, None)) for temp_list in izip_longest(*a)]
print(averages)
[2.0, 3.0, 4.0, 6.0]
不知道关于numpy逻辑最快的方法是什么,但这肯定比您自己的代码效率更高。
如果您想要更快的纯python解决方案:
from itertools import izip_longest, imap
a = [[1, 2, 3],
[2, 3, 4],
[3, 4, 5, 6]]
def avg(x):
x = filter(None, x)
return sum(x, 0.0) / len(x)
filt = imap(avg, izip_longest(*a))
print(list(filt))
[2.0, 3.0, 4.0, 6.0]
如果数组中的0不能正常工作,因为0将被视为Falsey,在这种情况下,您将不得不使用list comp进行过滤,但它仍然会更快:
def avg(x):
x = [i for i in x if i is not None]
return sum(x, 0.0) / len(x)
filt = imap(avg, izip_longest(*a))
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句