Python 将列表拆分为单独但重叠的块

Python 将列表拆分为单独但重叠的块,python,list,Python,List,假设我有一个列表a A = [1,2,3,4,5,6,7,8,9,10] 我想按照以下顺序使用上面的列表创建一个新列表(比如B) B = [[1,2,3], [3,4,5], [5,6,7], [7,8,9], [9,10,]] 即前3个数字为A[0,1,2],后3个数字为A[2,3,4],依此类推。 我相信对于这种操作,numpy中有一个函数。这个“复制”表示np.split-对于不重叠的split来说这很好。示例(在close?之后添加)重叠,每个子阵列上有一个元素。加上一个0 有一些很

假设我有一个列表
a

A = [1,2,3,4,5,6,7,8,9,10]
我想按照以下顺序使用上面的列表创建一个新列表(比如
B

B = [[1,2,3], [3,4,5], [5,6,7], [7,8,9], [9,10,]]
即前3个数字为
A[0,1,2]
,后3个数字为
A[2,3,4]
,依此类推。

我相信对于这种操作,
numpy
中有一个函数。

这个“复制”表示
np.split
-对于不重叠的split来说这很好。示例(在close?之后添加)重叠,每个子阵列上有一个元素。加上一个0

有一些很好的列表答案,有各种形式的生成器或列表理解,但乍一看,我没有看到任何允许重叠的答案-尽管通过巧妙地使用迭代器(如
iterator.tee
)应该是可能的

我们可以把这归咎于拙劣的问题措辞,但这不是重复

根据示例和注释进行操作:


这里我的窗口大小是3,即每个被拆分的列表应该有3个元素第一次拆分
[1,2,3]
,步长是2,所以第二次拆分的开始应该从第三个元素开始,第二次拆分分别是[3,4,5]

下面是一个高级解决方案,它使用的是

In [64]: ast=np.lib.index_tricks.as_strided  # shorthand 

In [65]: A=np.arange(1,12)

In [66]: ast(A,shape=[5,3],strides=(8,4))
Out[66]: 
array([[ 1,  2,  3],
       [ 3,  4,  5],
       [ 5,  6,  7],
       [ 7,  8,  9],
       [ 9, 10, 11]])
我增加了
A
的范围,因为我不想处理0键盘

选择目标
形状
很容易,5组3个。选择跨步需要更多关于跨步的知识

In [69]: x.strides
Out[69]: (4,)
1d跨步,或从一个元素跨步到下一个元素,是4字节(一个元素的长度)。从一行到下一行的步骤是原始行的2个元素,或2*4字节

当您大步前进时
生成一个视图。因此,更改其中的图元将影响原始图元,并可能更改重叠值。添加
.copy()
进行复制;使用跨步数组的数学运算也将生成一个副本

更改跨距可以得到不重叠的行-但要注意形状-可以访问原始数据缓冲区之外的值

In [82]: ast(A,shape=[4,3],strides=(12,4))
Out[82]: 
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 17]])

In [84]: ast(A,shape=[3,3],strides=(16,4))
Out[84]: 
array([[ 1,  2,  3],
       [ 5,  6,  7],
       [ 9, 10, 11]])
编辑 一个新函数提供了一个更安全的
版本

np.lib.strided_tricks.sliding_window_view(np.arange(1,10),3)[::2]

只需使用Python内置的列表理解和列表切片即可:

>>> A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> size = 3
>>> step = 2
>>> A = [A[i : i + size] for i in range(0, len(A), step)]
这将为您提供您想要的:

>>> A
[[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]]

但您必须编写几行代码,以确保代码不会因前所未有的大小/步长值而中断。

我编写的此函数可能会对您有所帮助,尽管它只输出长度为
len_chunk的填充块。

def重叠(数组,len_块,len_sep=1):
“”“返回输入'array'的所有完全重叠块的矩阵,其中包含一个块
“len_chunk”的长度和“len_sep”的分隔长度。从第一个完整字符开始
数组“”中的块
n_array=np.int(np.ceil((array.size-len_chunk+1)/len_sep))
array\u matrix=np.tile(数组,n\u数组)。重塑(n\u数组,-1)
columns=np.array((len_sep*np.arange(0,n_数组))。重塑(n_数组,-1)+np.tile(
np.arange(0,len_chunk),n_数组)。重塑(n_数组,-1)),dtype=np.intp)
行=np.array((np.arange(n_数组)。重塑(n_数组,-1)+np.tile(
np.zero(len_chunk),n_数组。重塑(n_数组,-1)),dtype=np.intp)
返回数组\矩阵[行,列]

那么,根据什么规则分割列表?三人一组,带填充?请明确。也请看这里我的窗口大小是3,即每个拆分列表应该有3个元素,第一个拆分
[1,2,3]
,步长是2,所以第二个拆分开始应该从第三个元素开始,第二个拆分分别是[3,4,5]。请将此添加到您的问题中,这并不清楚。你自己有没有尝试过解决这个问题?好的,我将用我尝试过的代码编辑我的问题。另一个列表表达式是
list(zip(*[x[I::2]表示范围内的I(3)])
。如果你要根据评论重新打开一个问题,至少要编辑问题以包含额外的信息。我现在已经结束了这个问题,因为它还不清楚。@Martijn我得到了我的答案。请打开这个问题。它将对其他一些人有用。