我们说我有一个列表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
中有一种功能可用于此类操作。
答案 0 :(得分:4)
重复' Paritition array into N chunks with Numpy建议np.split
- 对于非重叠拆分非常好。示例(在关闭后添加?)重叠,每个子数组中有一个元素。加上垫子为0。
How do you split a list into evenly sized chunks?有一些很好的列表答案,有各种形式的生成器或列表理解,但乍一看我没有看到任何允许重叠 - 尽管聪明地使用迭代器(例如iterator.tee
)这应该是可能的。
我们可以将这归咎于不好的问题措辞,但这不是重复。
使用示例和评论:
这里我的窗口大小为3.,即每个拆分列表应该有3个元素,首先拆分
[1,2,3]
,步长为2,所以第二个拆分开始应该从第3个元素开始,第2个拆分是[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]])
我增加了A
的范围,因为我不想处理0 pad。
选择目标shape
很容易,5套3.选择步幅需要更多关于跨步的知识。
In [69]: x.strides
Out[69]: (4,)
1d跨步或从一个元素步进到下一个元素是4个字节(长度为1个元素)。从一行到下一行的步骤是原始的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]])
答案 1 :(得分:4)
只需使用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]]
但是你必须写几行来确保你的代码不会破坏前所未有的size / step值。
答案 2 :(得分:0)
我编写的此函数可能会为您提供帮助,尽管它仅输出长度为len_chunk
的填充块:
def overlap(array, len_chunk, len_sep=1):
"""Returns a matrix of all full overlapping chunks of the input `array`, with a chunk
length of `len_chunk` and a separation length of `len_sep`. Begins with the first full
chunk in the array. """
n_arrays = np.int(np.ceil((array.size - len_chunk + 1) / len_sep))
array_matrix = np.tile(array, n_arrays).reshape(n_arrays, -1)
columns = np.array(((len_sep*np.arange(0, n_arrays)).reshape(n_arrays, -1) + np.tile(
np.arange(0, len_chunk), n_arrays).reshape(n_arrays, -1)), dtype=np.intp)
rows = np.array((np.arange(n_arrays).reshape(n_arrays, -1) + np.tile(
np.zeros(len_chunk), n_arrays).reshape(n_arrays, -1)), dtype=np.intp)
return array_matrix[rows, columns]