2024-04-18 05:23:55 发布
网友
我需要找出一维列表中项目的平均值: 例如:L=[123678234256789,----] 首先,我需要从列表。因此提供如下结果列表:reslist=[416489.25426.33522.5789---]。 用一个简单的python代码做这件事对任何一个Plz来说都是很有帮助的。。在
下面是一个使用递归的解决方案:
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)]
演示
输出:
[416.0, 489.25, 426.3333333333333, 522.5, 789.0]
所以对于每个索引i,您需要L[i]到L[-1]的平均值,对吗?在
i
L[i]
L[-1]
首先,让我们编写一个简单的average函数:
average
def average(values): return sum(values) / len(values)
现在,我们可以将描述转换为代码:
您似乎还希望以某种未指定的方式对事物进行舍入(489.25舍入为489,但522.5保留为522.5);如果您可以描述规则,我可以演示如何实现它,但我无法从您的示例中猜出规则。在
当然,如果L是long,这并不是很有效,因为它将执行len(L)**2 / 2加法。有没有一种方法可以在len(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()
第一步和最后一步都很简单:只需在开头和结尾处颠倒列表。剩下的呢?在
首先,^{}只接受任何iterable,并返回一个迭代器和累计和。所以它给你i[0],然后是i[0] + i[1],然后是{},等等。但是,因为它记住了最后的部分和,所以每个步骤只需要一个加法。换句话说,它给你0 + i[0],然后result[0] + i[1],然后result[1] + i[2]。如果您想了解它是如何工作的(或者如果您使用的是没有accumulate的旧版本的Python),链接的文档将展示如何自己构建它。在
i[0]
i[0] + i[1]
0 + i[0]
result[0] + i[1]
result[1] + i[2]
accumulate
然后,我们将每个部分和除以索引(+1,因为Python索引是从0开始的)得到运行平均值。列表理解应该是显而易见的;如果您不知道^{}函数,这是唯一聪明的地方。在
这不是唯一的办法。您还可以使用functools.reduce,或者显式循环,或者通过累加器传递来构建尾部递归函数,或者一个简单的递归函数,或者……尽可能多地编写这些函数可能是一个很好的练习。可能只有一种显而易见的方法可以做到,但有时在你尝试几种方法之前,哪一种方法是显而易见的。:)
functools.reduce
另一种方法是用numpy。罗高斯删除了他过于简单的回答,但这只是一个开始。在
首先,最简单的部分是:反转列表,并将其填充到numpy数组中:
a = np.array(reversed(L))
现在,诀窍是写一个向量化的运行和。好吧,numpy带有^{},用N个1进行卷积得到一个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和{}也是numpy数组,这使得它更简单。在
L
无论如何,使用NUMPY的部分是操作简单(注意我是如何将一个数组除以另一个数组,而不是写一个列表理解),通常快大约10倍(所有循环和算术都是在C中进行的,或者偶尔是C++或FORTRAN,而不是在Python中)。缺点是你必须弄清楚如何将每个循环变成一个合理的数学运算。(如果您不知道convolve是做什么的,您绝对不会想到在这里使用它。)
convolve
下面是一个使用递归的解决方案:
演示
^{pr2}$输出:
所以对于每个索引
i
,您需要L[i]
到L[-1]
的平均值,对吗?在首先,让我们编写一个简单的
average
函数:现在,我们可以将描述转换为代码:
^{pr2}$您似乎还希望以某种未指定的方式对事物进行舍入(489.25舍入为489,但522.5保留为522.5);如果您可以描述规则,我可以演示如何实现它,但我无法从您的示例中猜出规则。在
当然,如果L是long,这并不是很有效,因为它将执行
len(L)**2 / 2
加法。有没有一种方法可以在len(L)
内完成?当然,只是有点复杂。例如:第一步和最后一步都很简单:只需在开头和结尾处颠倒列表。剩下的呢?在
首先,^{} 只接受任何iterable,并返回一个迭代器和累计和。所以它给你},等等。但是,因为它记住了最后的部分和,所以每个步骤只需要一个加法。换句话说,它给你
i[0]
,然后是i[0] + i[1]
,然后是{0 + i[0]
,然后result[0] + i[1]
,然后result[1] + i[2]
。如果您想了解它是如何工作的(或者如果您使用的是没有accumulate
的旧版本的Python),链接的文档将展示如何自己构建它。在然后,我们将每个部分和除以索引(+1,因为Python索引是从0开始的)得到运行平均值。列表理解应该是显而易见的;如果您不知道^{} 函数,这是唯一聪明的地方。在
这不是唯一的办法。您还可以使用
functools.reduce
,或者显式循环,或者通过累加器传递来构建尾部递归函数,或者一个简单的递归函数,或者……尽可能多地编写这些函数可能是一个很好的练习。可能只有一种显而易见的方法可以做到,但有时在你尝试几种方法之前,哪一种方法是显而易见的。:)另一种方法是用numpy。罗高斯删除了他过于简单的回答,但这只是一个开始。在
首先,最简单的部分是:反转列表,并将其填充到numpy数组中:
现在,诀窍是写一个向量化的运行和。好吧,numpy带有^{} ,用N个1进行卷积得到一个N+M-1窗口和。那么,如果窗口和整个数组一样宽,会发生什么呢?我们得到一个窗口求和,它的长度几乎是我们需要的两倍,其中第一个len(L)值是运行和。所以:
然后我们只需除以索引,就像在itertools版本中一样:
现在我们只要把它颠倒过来,再把它变成一个列表:
当然,在现实生活中,您可能希望}也是numpy数组,这使得它更简单。在
L
和{无论如何,使用NUMPY的部分是操作简单(注意我是如何将一个数组除以另一个数组,而不是写一个列表理解),通常快大约10倍(所有循环和算术都是在C中进行的,或者偶尔是C++或FORTRAN,而不是在Python中)。缺点是你必须弄清楚如何将每个循环变成一个合理的数学运算。(如果您不知道
convolve
是做什么的,您绝对不会想到在这里使用它。)相关问题 更多 >
编程相关推荐