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

Ran*_*ski 2 python list

假设我有一个清单 A

A = [1,2,3,4,5,6,7,8,9,10]
Run Code Online (Sandbox Code Playgroud)

我想B按以下顺序使用上述列表创建一个新列表(例如)。

B = [[1,2,3], [3,4,5], [5,6,7], [7,8,9], [9,10,]]
Run Code Online (Sandbox Code Playgroud)

即前三个数字为A[0,1,2],后三个数字为A[2,3,4],依此类推。

我相信其中有一种numpy用于此类操作的功能。

hpa*_*ulj 5

Numpy建议将“重复” Paritition数组分成N个块,np.split这对于不重叠的拆分是很好的。该示例(在close?之后添加)重叠,每个子数组一个元素。加上它填充0。

如何将列表分成大小均匀的块?可以使用各种形式的生成器或列表理解来提供一些很好的列表答案,但是乍一看,尽管可以巧妙地使用迭代器(例如iterator.tee),但我没有看到任何允许重叠的内容。

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

通过示例和注释进行工作:

在这里,我的窗口大小为3,即每个拆分列表应首先拆分3个元素[1,2,3],步长为2,因此第二个拆分开始应从3rd个元素开始,第二个拆分分别为[3,4,5]。

这是使用 as_strided

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]])
Run Code Online (Sandbox Code Playgroud)

我增加了范围,A因为我不想处理0垫。

选择目标shape很容易,只有5组,共3组。选择步幅需要更多有关步幅的知识。

In [69]: x.strides
Out[69]: (4,)
Run Code Online (Sandbox Code Playgroud)

从一个元素到另一个元素的1d步长为4个字节(一个元素的长度)。从一行到下一行的步长是原始元素的2个元素,即2 * 4字节。

as_strided产生一个视图。因此,更改其中的元素将影响原始元素,并可能更改重叠的值。添加.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]])
Run Code Online (Sandbox Code Playgroud)


cs9*_*s95 5

只需将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)]
Run Code Online (Sandbox Code Playgroud)

这为您提供了您想要的东西:

>>> A
[[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]]
Run Code Online (Sandbox Code Playgroud)

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

  • 另一个列表表达式是`list(zip(* [x [i :: 2] for range(3)])))。 (2认同)