Python中列表中两个连续元素的平均值

时间:2013-12-11 18:52:18

标签: python

我有一个偶数浮点数列表:

  

[2.34,3.45,4.56,1.23,2.34,7.89,......]。

我的任务是计算1和2个元素的平均值,3和4,5和6等。在Python中执行此操作的简短方法是什么?

5 个答案:

答案 0 :(得分:16)

data = [2.34, 3.45, 4.56, 1.23, 2.34, 7.89]
print [(a + b) / 2 for a, b in zip(data[::2], data[1::2])]

说明:

data[::2]是元素2.34, 4.56, 2.34

data[1::2]是元素3.45, 1.23, 7.89

zip将它们合并为2个元组:(2.34, 3.45), (4.56, 1.23), (2.34, 7.89)

答案 1 :(得分:8)

如果名单不长,Paul Draper的回答很简单。如果 非常长,您可能需要考虑其他两个选项之一。


首先,使用迭代器,可以避免复制巨大的临时列表:

avgs = [(a + b) / 2 for a, b in zip(*[iter(data)]*2)]

这实际上是一样的,但懒惰,这意味着它只需要在内存中存储一​​个值(好吧,三个值-a,b和平均值)而不是全部他们。

  • iter(data)为数据创建一个惰性迭代器。
  • [iter(data)]*2创建一个列表,其中包含对同一个迭代器的两个引用,因此当一个进程前进时,另一个也会进行。
  • 然后我们使用相同的zip和列表理解,保罗已经很好地解释了。 (在Python 2.x中,与{3.}相反,zip并非懒惰,因此您需要使用itertools.izip而不是zip。)

如果你实际上并不需要结果列表,只是你可以迭代的东西,将外部方括号更改为括号,它就变成了一个生成器表达式,这意味着它为你提供了一个迭代器而不是一个列表,并且你'根本不存储任何东西。

请注意,itertools文档有grouper的配方可以处理棘手的问题(您也可以在第三方模块more-itertools中找到它),因此您可以只需编写grouper(data, 2)而不是zip(*[iter(data)]*2),如果您经常这样做,这肯定会更具可读性。如果您需要更多说明,请参阅How grouper works


或者,您可以使用NumPy数组而不是列表:

data_array = np.array(data)

然后你可以这样做:

avg_array = (data_array[::2] + data_array[1::2]) / 2

这不仅更简单(不需要显式循环),它的速度也提高了约10倍,并占用了大约1/4的内存。


如果你想把它推广到任意长度的组......

对于迭代器解决方案,它很简单:

[sum(group) / size for group in zip(*[iter(data)]*size)]

对于NumPy解决方案,它有点棘手。你必须动态地为data[::size]data[1::size],...,data[size-1::size]上的迭代器创建一些东西,如下所示:

sum(data[x::size] for x in range(size)) / size

在NumPy中还有其他方法可以做到这一点,但只要size不是太大,这就没问题了 - 它的优点是完全相同的技巧适用于Paul Draper的解决方案:

[sum(group) / size for group in zip(*(data[x::size] for x in range(size)))]

答案 2 :(得分:4)

s= [2.34, 3.45, 4.56, 1.23, 2.34, 7.89, ...]

res= [(s[i]+s[i+1])/2 for i in range(0, len(s)-1, 2)]

答案 3 :(得分:1)

使用 NumPy 找到连续两个值的平均值/平均值,这在时间和空间复杂度方面更有效:

data=np.array([1,2,3,4,5,6])
k=2 #In your case
data1=np.mean(data.reshape(-1, k), axis=1)

答案 4 :(得分:0)

只需使用索引即可完成任务。

举个简单的例子,

avg = []
list1 = [2.34, 3.45, 4.56, 1.23, 2.34, 7.89]

for i in range(len(list1)):
    if(i+1 < len(list1):
        avg.append( (list1[i] + list1[i+1]) / 2.0 )

avg2 = []
avg2 = [j for j in avg[::2]] 

avg2就是你想要的。这可能很容易理解..