Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从不同长度的滚动窗口求和_Python_List_Sum - Fatal编程技术网

Python 从不同长度的滚动窗口求和

Python 从不同长度的滚动窗口求和,python,list,sum,Python,List,Sum,我试图使用不同长度的滚动窗口从列表的一部分中找到一个特定的总和。首先,我创建了一个基本的数字列表,然后尝试对生成的一些滚动窗口求和。不幸的是,这似乎不可能做到 foo = [] for x in range (1, 200): foo.append(x) def subsequences(iterable, length): return [iterable[i: i + length] for i in xrange(len(iterable) - length + 1)

我试图使用不同长度的滚动窗口从列表的一部分中找到一个特定的总和。首先,我创建了一个基本的数字列表,然后尝试对生成的一些滚动窗口求和。不幸的是,这似乎不可能做到

foo = []

for x in range (1, 200): 
    foo.append(x)

def subsequences(iterable, length):
    return [iterable[i: i + length] for i in xrange(len(iterable) - length + 1)]

for i in range (1, len(foo)):
    print sum(subsequences(foo, i))
我收到的错误是:

TypeError:不支持+:“int”和“list”的操作数类型


有没有办法生成每个子序列并求和?

检查
子序列()
的输出会发现问题:您试图将一系列列表添加到一起,以实现每个列表中包含的整数值之和

print(subsequences(foo, i))
# [[1], [2], [3], [4], [5], [6], [7], [8] ...]
这不是Python内置的
sum
的设计目的,但如果使用Numpy的
sum
,此操作将起作用:

import numpy as np

# ... 

for i in range (1, len(foo)):
    print (np.sum(subsequences(foo, i)))
输出:

19900
39600
59100
78400
97500
116400
...

或者,在应用
sum
之前,您可以提取每个列表中的值,但使用Numpy可以让您的代码保持原样,只需添加
np即可。

您只需对子序列求和:

[sum(subsequence) for subsequence in subsequences(foo, i)]

当您想对数字求和时,您正在尝试对列表求和。如果您运行以下简单的操作:

>>> print(sum([[1], [2]]))
.....
TypeError: unsupported operand type(s) for +: 'int' and 'list'
您将复制您的
TypeError
,这是当前程序的行为

要解决这个问题,只需分解问题

首先查看一次迭代的每个子序列,例如
2

print([x for x in subsequence(foo, 2)])
# [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], ......]
然后将每个子序列和:

print([sum(x) for x in subsequences(foo, 2)])
# [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, ......]
然后将此列表相加:

print(sum(sum(x) for x in subsequences(foo, 2)))
# 39600
然后,您的最终for循环将在
i
的所有迭代中正常运行:

for i in range (1, len(foo)):
    print(sum(sum(x) for x in subsequences(foo, i)))
其行为正确:

19900
39600
59100
78400
97500
116400
135100
153600
171900
190000
207900
225600
243100
......

您可以使用
map
sum
向下推列表嵌套一级;例如:

map(sum, subsequences(foo, 4))

# [10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 66, 70, ...
一种更有效的方法是首先计算累积和,然后在适当的偏移量处取成对差。您似乎在使用Python2,这很遗憾,因为Python3有一个累积函数。在python 2上,我们需要构建自己的:

def partialsums(a):
    def runner(a):
        runner.tot += a
        return runner.tot
    runner.tot = 0
    return [0] + [runner(i) for i in a]

ps = partialsums(foo)
现在,您只需执行以下操作:

[r-l for r, l in zip(ps[4:], ps[:-4])]
# [10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 66, 70, ...

[r-l for r, l in zip(ps[100:], ps[:-100])]
# [5050, 5150, 5250, 5350, 5450, 5550, 5650, 5750, 5850, 5950, 6050, ...

最后一个示例使用直接法进行的算术运算略低于10000次,而使用差分法进行的算术运算仅为300次。在这300次运算中,200次只需执行一次,就可以用于其他窗口长度。

但是。。。然后你必须安装numpy@Ben如果您有
pip
@RoadRunner,那么这很容易。上次我尝试时遇到了依赖性问题。但是,即使它变得非常琐碎,我也不认为为
numpy.sum
安装整个东西是值得的。就我的观点而言,无论如何安装它都有合理的理由。