我有一个numpy数组,我想分开一定的维度。在拆分数组时,我需要在前一个元素的前导部分前面(到每个元素的开头)。例如,
让我的数组为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
。让我的split_size = 2
和pad_length = 1
。 split_size
将始终是数组长度的除数。我得到的分裂看起来像,
[random, 0, 1], [1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]
。我的分裂都是前一个元素的最后一个值。
毋庸置疑,我的数组是多维的,我需要一种高效的矢量化方法来实现这一点。
在这里,我可以提供random
。
答案 0 :(得分:2)
听起来像as_strided
的工作。
as_strided
在数组上返回内存有效的视图,可用于检索数组上的移动窗口。关于它的numpy文档很少,但有一些不错的博客文章,online slide decks和SO issues,你可以找到更详细的解释。
>>> import numpy as np
>>> from numpy.lib.stride_tricks import as_strided
>>> a = np.arange(10)
>>> split_size = 2
>>> pad_length = 1
>>> random = -9
>>> # prepend the desired constant value
>>> b = np.pad(a, (pad_length, 0), mode='constant', constant_values=random)
>>> # return a memory efficient view on the array
>>> as_strided(b,
... shape=(b.size//split_size, split_size + pad_length),
... strides=(b.strides[0]*split_size, b.strides[0]))
...
array([[-9, 0, 1],
[ 1, 2, 3],
[ 3, 4, 5],
[ 5, 6, 7],
[ 7, 8, 9]])
请注意,如果新步幅超出范围,您将看到相邻内存的内存内容出现在数组的末尾。
答案 1 :(得分:1)
这里列出的是strides
的另一种方法,可以看作是作弊的东西,因为我们会从输入数组的开头向后跨越分配给它的内存隐式地使用填充版本并实际将值分配到最后的待填充区域。
以下是它的样子 -
def padded_sliding_windows(a, split_size, pad_length, padnum):
n = a.strides[0]
L = split_size + pad_length
S = L - pad_length
nrows = ((a.size + pad_length -L)//split_size)+1
strided = np.lib.stride_tricks.as_strided
out = strided(a[split_size - 1:], shape=(nrows,L), strides=(S*n,-n))[:,::-1]
out[0,:pad_length] = padnum
return out
很少有样本运行 -
In [271]: a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [272]: padded_sliding_windows(a, split_size = 2, pad_length = 1, padnum = 100)
Out[272]:
array([[100, 0, 1],
[ 1, 2, 3],
[ 3, 4, 5],
[ 5, 6, 7],
[ 7, 8, 9],
[ 9, 10, 11]])
In [273]: padded_sliding_windows(a, split_size = 3, pad_length = 2, padnum = 100)
Out[273]:
array([[100, 100, 0, 1, 2],
[ 1, 2, 3, 4, 5],
[ 4, 5, 6, 7, 8],
[ 7, 8, 9, 10, 11]])
In [274]: padded_sliding_windows(a, split_size = 4, pad_length = 2, padnum = 100)
Out[274]:
array([[100, 100, 0, 1, 2, 3],
[ 2, 3, 4, 5, 6, 7],
[ 6, 7, 8, 9, 10, 11]])
答案 2 :(得分:0)
接下来是:
arr = np.array([0,1,2,3,4,5,6,7,8,9])
[arr[max(0, idx-1):idx+2] for idx in range(0, len(arr), 2)]
唯一的区别是第一个没有前导random
,正如你所说的那样。