[英]Replace None in list with average of last 3 non-None entries when the average is above the same entry in another list
我有两个列表:
dataa = [11, 18, 84, 51, 82, 1, 19, 45, 83, 22]
datab = [1, None, 40, 45, None, None, 23, 24, None, None]
对于前 3 个条目大于数据条目的任何实例,我需要替换 datab 中的所有 None(请参见下面的演练示例)。 忽略没有 3 个先前非无条目的条目以进行平均以与 dataa 进行比较。
我的第一次尝试是这样的:
for i in range(len(dataa)):
if (datab[i] == None):
a = (datab[i-3]+datab[i-2]+datab[i-1])/3
if ((datab[i-3]+datab[i-2]+datab[i-1])/3 > dataa[i]):
datab[i] = dataa[i]
在前 3 个中有一个为 None 的情况下,尝试计算前三个的平均值会出错。 我试图保持总计,但其中一些失败了。
c = 0;
a = 0;
for i in range(len(dataa)):
c = c + 1
if (datab[i] == None):
if (a > dataa[i]):
datab[i] = a
else:
if (c > 2):
a = (a * 3 + datab[i])/3
这也没有按预期工作。
从这个样本数据中,我预计:
(1+40+45)/3 = 28.66
我们也保持原样。28.66 > 1
),因此设置为 28.66 平均值。(28.66+23+24)/3 = 25.22
不大于 83,因此保留原样。25.22>22
),因此将其设置为 25.22 平均值。正确的预期 output:
[1, None, 40, 45, None, 28.66, 23, 24, None, 25.22]
让我们使用collections.deque
来跟踪要平均的数字 window,因为从deque
顶部弹出比从列表顶部弹出便宜。
感谢@ShadowRanger 指出deque
的maxlen
特性,它允许我们 append 一个元素,如果需要,deque 会自动弹出左边的元素。
from collections import deque
dataa = [11, 18, 84, 51, 82, 1, 19, 45, 83, 22]
datab = [1, None, 40, 45, None, None, 23, 24, None, None]
result = []
moving_avg = 0
sliding_window = deque(maxlen=3)
# Iterate over the two lists simultaneously
for a, b in zip(dataa, datab):
# If b already has a value
# Or the window has less than three items
# Or the average is less than the element of dataa
if b is not None or len(sliding_window) < 3 or moving_avg < a:
# Append the element of datab to result
result.append(b)
else:
# Else, append the moving average
result.append(moving_avg)
# If the value we just appended to our result is not None
# Then append it to the sliding window
if result[-1] is not None:
sliding_window.append(result[-1])
# Recalculate moving average
moving_avg = sum(sliding_window) / len(sliding_window)
print(result)
# [1, None, 40, 45, None, 28.666666666666668, 23, 24, None, 25.222222222222225]
您可以通过跟踪从双端队列中弹出的元素并使用它来计算移动平均值来节省一些计算时间,但是对于大小为 3 的双端队列来说,这无论如何都不是什么大问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.