我需要在一维列表中找到项目的平均值: 例如:L = [123,678,234,256,789,-----] 首先,我需要从列表中的最后一项开始获得运行平均值。因此,提供如下结果列表:reslist = [416,489.25,426.33,522.5,789 ---]。 Plz可以任何人在python中建议一个简单的代码,这样做会有所帮助..
答案 0 :(得分:2)
因此,对于每个索引i
,您需要L[i]
到L[-1]
的平均值,对吗?
首先,让我们编写一个简单的average
函数:
def average(values):
return sum(values) / len(values)
现在,我们可以将描述翻译成代码:
running_averages = [average(L[i:]) for i in range(len(L))]
你似乎也希望以某种未指明的方式对事物进行舍入(489.25舍入为489,但522.5为522.5);如果你可以描述规则,我可以展示如何实现它,但我不能从你的例子中猜出规则。
当然,如果L很长,这个效率不高,因为它会增加len(L)**2 / 2
次。有没有办法我们可以在len(L)
中做到这一点?当然,它只是有点复杂。例如:
partial_sums = itertools.accumulate(reversed(L))
averages = [value/(i+1) for i, value in enumerate(partial_sums)]
averages.reverse()
第一步和最后一步很简单:只需在开头然后结束时反转列表即可。但其余的呢?
首先,accumulate
只接受任何迭代,并返回带累积和的迭代器。因此它会为您i[0]
,然后i[0] + i[1]
,然后i[0] + i[1] + i[2]
,等等。但是,因为它会记住最后的部分和,所以每个步骤只需要一次添加。换句话说,它会为您提供0 + i[0]
,然后是result[0] + i[1]
,然后是result[1] + i[2]
。如果你想看看它是如何工作的(或者如果你使用的是没有accumulate
的旧版Python),那么链接的文档将展示你如何自己构建它。
然后,我们只是将每个部分和除以索引(+ 1,因为Python索引从0开始)以获得运行平均值。列表理解应该是显而易见的;如果你不知道enumerate
函数,那就是唯一聪明的一点。
这不是唯一的方法。您也可以使用functools.reduce
或显式循环,或者通过累加器传递或者一个天真的递归函数构建尾递归函数,或者......尝试编写与您一样多的函数可能是一个很好的练习能够。可能只有一种显而易见的方法可以做到这一点,但有时候直到你尝试一些方法并不明显哪一种是明显的方法。 :)
另一种方法是使用numpy。 rogaos删除了他太简单的答案,但这是一个开始。
首先,简单的部分:反转列表,并将其塞进一个numpy数组:
a = np.array(reversed(L))
现在,诀窍是写一个矢量化的运行总和。好吧,numpy带有convolve
,并且与N次运行进行卷积会给你一个N + M-1窗口的总和。那么,如果窗口和整个数组一样宽,会发生什么?我们得到的窗口总和几乎是我们需要的两倍,其中第一个len(L)值是运行总和。所以:
running_sums = np.convolve(a, np.ones(len(L)))[:len(L)]
然后我们只是按指数划分,就像在itertools版本中一样:
running_means = running_sums / np.arange(1, len(L)+1)
现在我们只需将其反转并将其转回列表:
reslist = list(reversed(running_means))
当然,在现实生活中,你可能希望L
和reslist
也是numpy数组,这使得它更简单。
无论如何,使用numpy的好处是一些操作更简单(请注意我是如何将一个数组分成另一个数组而不是编写列表解析),并且通常快约10倍(所有循环和算术运算都需要放在C中,或偶尔使用C ++或Fortran,而不是Python)。缺点是你必须弄清楚如何将每个循环转变为合理的数学运算。 (如果你不知道convolve
做了什么,你就不会想到在这里使用它。)
答案 1 :(得分:0)
这是一个使用递归的解决方案:
def runningMean(seq, n=0, total=0):
if not seq:
return []
total = total+seq[-1]
return runningMean(seq[:-1], n=n+1, total=total) + [total/float(n+1)]
<强>样本强>
print(runningMean([123,678,234,256,789]))
输出:
[416.0, 489.25, 426.3333333333333, 522.5, 789.0]