簡體   English   中英

Python中列表中兩個連續元素的平均值

[英]Average of two consecutive elements in the list in Python

我有一個偶數個浮點數的列表:

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

我的任務是計算 1 和 2 個元素、3 和 4、5 和 6 等元素的平均值。在 Python 中執行此操作的簡便方法是什么?

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)

如果列表不是太長,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.x 不同, zip不是懶惰的,所以你想使用itertools.izip而不是zip 。)

如果您實際上不需要結果列表,而只是您可以迭代的內容,請將外部方括號更改為括號,它將成為生成器表達式,這意味着它為您提供了一個迭代器而不是一個列表,並且您不會存儲什么都沒有。

請注意, itertools文檔有一個grouper的配方,它可以做一些棘手的事情(你也可以在第三方模塊more-itertools找到它),所以你可以只寫grouper(data, 2)而不是zip(*[iter(data)]*2) ,如果您經常這樣做,這肯定更具可讀性。 如果您需要更多解釋,請參閱石斑魚的工作原理


或者,您可以使用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)))]
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)]

使用 NumPy 找到連續兩個值的平均值/平均值,這在時間和空間復雜度方面更有效:

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

只需為任務使用索引。

舉個簡單的例子,

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 就是你想要的。 這可能很容易理解..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM