我有很多列表(时间序列)
dictionary = {'a': [1,2,3,4,5], 'b': [5,2,3,4,1], 'c': [1,3,5,4,6]}
我想对另一个人求平均值:
merged = {'m': [2.33,2.33,3.66,4.0,4.0]}
有没有一种聪明的方法可以找到它?
如果列表具有不同的长度并且我想要可用的平均值,或者假设所有列表在同一时间段内发生,尽管数据点数不同,该怎么办?
答案 0 :(得分:2)
鉴于你用numpy和scipy标记了这个,我假设它可以使用科学的python函数。那么完成第一项任务的简洁方法就是
$ ipython --pylab
>>> dictionary = {'a': [1,2,3,4,5], 'b': [5,2,3,4,1], 'c': [1,3,5,4,6]}
>>> map(mean, np.array(dictionary.values()).transpose())
[2.3333333333333335, 2.3333333333333335, 3.6666666666666665, 4.0, 4.0]
当然,您可以将其放入带有密钥的字典中。并将结果四舍五入,以便以您指定的形式得到结果。
至于处理缺失值或不同长度的数组, 您首先需要决定如何处理缺失的数据。 你问第二个问题的方式感觉太模糊了。
答案 1 :(得分:0)
一个简单的数据方法就是
from statistics import mean
dictionary = {'a': [1,2,3,4,5], 'b': [5,2,3,4,1], 'c': [1,3,5,4,6]}
merged = {'m': [mean(values) for values in zip(*dictionary.values())]}
merged
#>>> {'m': [2.3333333333333335, 2.3333333333333335, 3.6666666666666665, 4.0, 4.0]}
对于较旧的Python 3版本,请将statistics.mean
替换为sum(values) / len(values)
。对于Python 2,您需要from __future__ import division
或使用float(len(values)
。
如果你想要线性插值,那也很容易:
from statistics import mean
import numpy
dictionary = {'a': [1,2,3,4,5], 'b': [5,2,3,1], 'c': [1,3,5,4,6]}
def interpolate_many(lists):
maxlen = max(map(len, lists))
interpolation_target = numpy.linspace(0, 1, maxlen)
for lst in lists:
x_values = numpy.linspace(0, 1, len(lst))
yield numpy.interp(interpolation_target, x_values, lst)
interpolated = interpolate_many(dictionary.values())
merged = {'m': [mean(values) for values in zip(*interpolated)]}
merged
#>>> {'m': [2.3333333333333335, 2.5833333333333335, 3.5, 3.5, 4.0]}
所有这一切都是对列表进行预处理,以便将短列表拉伸到最大长度(maxlen
,如果您愿意,可以更改)。然后它运行先前的代码。
答案 2 :(得分:0)
以下代码根据找到的元素数量对数组进行平均。
dictionary = {'a': [1,2,3,4,5], 'b': [5,2,3,4,1], 'c': [1,3,5,4,6]}
mergerd = {'m': []}
i = 0
count = 0
num = len(dictionary)
while True:
mergerd['m'].append(0)
for key in dictionary: #for each entry in the dictionary
if (len(dictionary[key]) <= i): #if the list for that entry doesn't have a element
continue
mergerd['m'][i] += dictionary[key][i]
count += 1
if count == 0: #if there were no more elements
mergerd['m'].pop()
break
mergerd['m'][i] = mergerd['m'][i]/count
count = 0
i += 1
print(mergerd['m'])
产生以下输出
[2.3333333333333335, 2.3333333333333335, 3.6666666666666665, 4.0, 4.0]
if dictionary was equal to {'a': [1,2,3,4,5,3], 'b': [5,2,3,4,1,1,1], 'c': [1,3,5,4,6]}
# then the following would be output
[2.3333333333333335, 2.3333333333333335, 3.6666666666666665, 4.0, 4.0, 2.0, 1.0]
合并数组的最后两个元素是2.0和1.0
2是因为只有两个数组有第6个元素,它们的值是3和1,所以(3 + 1)/ 2 = 2
1是因为只有一个数组有第7个元素,值为1,所以1/1 = 1
答案 3 :(得分:0)
您可以使用基本列表理解:
import numpy
dictionary = {'a': [1,2,3,4,5], 'b': [5,2,3,4,1], 'c': [1,3,5,4,6]}
vals = [dictionary.values()[i][j] for j in range(5) for i in range(3)]
vals = [vals[i:i+3] for i in range(0, len(vals), 3)]
merged = {}
merged['m'] = [numpy.mean(item) for item in vals)]
print merged #{'m': [2.3333333333333335, 2.3333333333333335, 3.6666666666666665, 4.0, 4.0]}