我有N个不同长度的大型列表,其中列表中的每个值代表长度为25的固定窗口上的信号.即,我每隔25秒/秒/等取信号的平均值,并将该值存储在一个列表.
我这样做是为了运行不同时间长度的不同实验/设备(所有倍数为25 btw).
即列表1是1000运行,列表1中1000/25 = 40值,列表2运行1025分钟,列表2中1025/25 = 41值,列表3是2525运行,2525/25 = 101 list3等中的值……
现在,为了便于比较,我想将每个列表重新缩放到相同数量的箱子,让我们说40个箱子.
事实上,list1resized长度将为40,其值不会改变,因为1000/40 = 25. list2resized将从41个值的长度变为40个值的长度,list3将从101个值的长度变为40个值的长度(同样所有列表现在具有相同的大小).
这就是问题所在.如何通过在适当的箱子上取加权平均值,将每个列表的大小调整为固定长度40?
一个例子将澄清这个问题.
list1 = [4.8, 6.9, ...] #40 values for the 1000 run
list2 = [5.6, 7.8, 8.9, 13.4, ...] #41 values for the 1025 run
list3 = [4.1, 5.6, 10.3, 9.8, 40, 30, 21.4, 3, 2,...] #101 values for the 2525 run
现在,调整大小的列表应如下所示:
list1resized = [4.8*25/25, 6.9*25/25,...] #40 values for the 1000 run
list2resized = [(5.6*25+7.8*0.625)/25.625, (7.8*24.375+8.9*1.275)/25.625, (23.725*8.9+1.9*13.4)/25.625,...] # 40 values, averaged accordingly, for the 1025 run
list3resized = [(4.1*25+5.6*25+10.3*13.125)/(63.125), (10.3*11.875+9.8*25+40*25+30*1.25)/(63.125),...] # 40 values, averaged accordingly, for the 2525 run
为了获得调整大小的列表中每个元素的平均值,我们对新调整大小的区间采用加权平均值(即,对于list1,平均值超过1000/40 = 25,对于list2,平均值超过1025/40 = 25.625,平均值超过列表3等2525/40 = 63.125).即,与我用于加权平均值的公式相同:
list1resized = [4.8*25/25, 6.9*25/25,...] #40 values for the 1000 run
list2resized = [(5.6*25+7.8*0.625)/25.625, (7.8*24.375+8.9*(25.65-24.375))/(25.625), (23.725*8.9+(25.625-23.725)*13.4)/(25.625),...] # 40 values, averaged accordingly, for the 1025 run
list3resized = [(4.1*25+5.6*25+10.3*13.125)/(63.125), (10.3*(25-13.125)+9.8*25+40*25+30*(63.125-25*3+13.125)))/(63.125),...] # 40 values, averaged accordingly, for the 2525 run
正如你所看到的,它可能会变得混乱,并且难以处理,但我正在寻找一个pythonic,优雅和快速的解决方案.
我必须多次为许多列表执行此操作,因此考虑运行时间会很好.
不确定您是否有任何想法,但非常感谢帮助.
谢谢.
解决方法:
这个时髦的[也许]解决方案怎么样?
首先是测量清单……
l = [5.6, 7.8, 8.9, 13.4]
复制每次测量25次(每秒一次……)
l1 = [item for sublist in [list(itertools.repeat(k,25)) for k in l] for item in sublist]
每秒标准化:
l2 = map(lambda x: x / 25., l1)
请参阅此SO帖子以获取将列表切成n个几乎相等的分区的函数(下面复制):
Python: Slicing a list into n nearly-equal-length partitions
def partition(lst, n):
division = len(lst) / float(n)
return [ lst[int(round(division * i)): int(round(division * (i + 1)))] for i in xrange(n) ]
定义列表的新长度
new_len = 2
将每秒列表缩减为您想要的部分数量:
l3 = partition(l2, new_len)
对每个分区中每秒的值求和
l4 = map(sum, l3)
标准化列表大小的差异
l5 = map(lambda x: x * new_len / float(len(l)), l4)
欣赏结果:
print l5