假设我有一个清单 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用于此类操作的功能。
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)
只需将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)
但是,您必须写几行代码,以确保代码不会因大小/步长的空前值而中断。