Numpy:生成嵌套数组

时间:2018-05-22 12:58:43

标签: python list numpy

我需要生成一个数组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]

如何实现?

2 个答案:

答案 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]])