我需要生成一个数组output
:
output = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]
使用input
:
input = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
如何实现?
答案 0 :(得分:3)
您可以使用列表理解。此外,使用enumerate
方法以返回枚举对象。
k=4
l = [input[index: index + k] for index, _ in enumerate(input[:-k + 1])]
输出
[[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9], [7, 8, 9, 10], [8, 9, 10, 11], [9, 10, 11, 12], [10, 11, 12, 13], [11, 12, 13, 14]]
如果您需要使用numpy
数组,请使用np.array
构造函数。
答案 1 :(得分:3)
您可以使用stride_stricks.as_strided
:
In [38]: from numpy.lib.stride_tricks import as_strided
In [39]: data = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14], dtype='int64')
In [40]: result = as_strided(data, shape=(11,4), strides=(8, 8))
Out[40]:
array([[ 1, 2, 3, 4],
[ 2, 3, 4, 5],
[ 3, 4, 5, 6],
[ 4, 5, 6, 7],
[ 5, 6, 7, 8],
[ 6, 7, 8, 9],
[ 7, 8, 9, 10],
[ 8, 9, 10, 11],
[ 9, 10, 11, 12],
[10, 11, 12, 13],
[11, 12, 13, 14]])
这里的想法是告诉as_strided
使用创建数组
(8, 8)
作为元素之间的步幅并使用
data = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14], dtype='int64')
作为基础数据。
由于int64
指定了64位整数的数组,因此每个元素之间用8个字节隔开。
stride=(A,B)
表示行中元素之间的步幅是B字节和行之间的步幅是A字节。所以
结果数组中元素(i, j)
的{{3}}为:
offset = i*8 + j*8
因此,越过一行也会使字节偏移量增加8个字节,向下一列也会使字节偏移量增加8个字节。
通常,形状(11,4)的int64数组具有(32,8)的步幅:
In [53]: np.arange(44).reshape(11,4)
Out[53]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31],
[32, 33, 34, 35],
[36, 37, 38, 39],
[40, 41, 42, 43]])
In [54]: np.arange(44).reshape(11,4).strides
Out[54]: (32, 8)
因为32告诉NumPy在基础数据中跳过32个字节(即4个8字节值)以找到列中的下一个值。
相反,在行之间使用8字节的步幅是导致每行中的值仅比前一行大一的值。
as_strided
返回基础数据的视图。虽然这非常节省内存(没有数据被复制;基本上不需要为result
数组分配新空间),但这也意味着修改data
会修改result
:
In [42]: data[1] = 100
In [43]: result
Out[43]:
array([[ 1, 100, 3, 4],
[100, 3, 4, 5],
[ 3, 4, 5, 6],
[ 4, 5, 6, 7],
[ 5, 6, 7, 8],
[ 6, 7, 8, 9],
[ 7, 8, 9, 10],
[ 8, 9, 10, 11],
[ 9, 10, 11, 12],
[ 10, 11, 12, 13],
[ 11, 12, 13, 14]])
使result
成为独立副本:
result = np.array(result)
然后修改data
不再影响result
:
In [46]: data[2] = 99
In [47]: result
Out[47]:
array([[ 1, 100, 3, 4],
[100, 3, 4, 5],
[ 3, 4, 5, 6],
[ 4, 5, 6, 7],
[ 5, 6, 7, 8],
[ 6, 7, 8, 9],
[ 7, 8, 9, 10],
[ 8, 9, 10, 11],
[ 9, 10, 11, 12],
[ 10, 11, 12, 13],
[ 11, 12, 13, 14]])