如何分割numpy数组保留前一个分割的几个元素?

问题描述:

我有一个numpy数组,我希望在某个维度上分割。在分割数组时,我需要在每个元素的开头添加前一个元素的尾部。例如,如何分割numpy数组保留前一个分割的几个元素?

让我的数组为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。让我的split_size = 2pad_length = 1split_size将始终是数组长度的除数。我的合成分割看起来像,

[random, 0, 1], [1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]。我的分割全部由前一个元素的最后一个值作为前缀。不用说,我的数组是多维的,我需要一个高效的矢量化方式来沿着一定的维度做到这一点。

在这里,我可以提供random的值。

+0

不会,我们需要填充的尾随方太,像给定输入:'split_size = 5,pad_length = 2'?所以,我猜测最后一行是:[随机随机] [7 8 9]。 – Divakar

+0

为什么?对于这些参数,我应该得到这个 - > [[随机,随机,0,1,2,3,4],[3,4,5,6,7,8,9]'。如果问题不明确,我会很乐意在您指导下改进它! – martianwars

+0

啊我得到了错误的参数。我的意思是如果'split_size = 3,pad_length = 2'? – Divakar

听起来像是as_strided的工作。

as_strided在阵列上返回一个高效的内存视图并可用于检索数组上的移动窗口。关于它的numpy文档很少,但有一些体面的博客文章,online slide decksSO 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]]) 

注意,如果新的步伐去出界,你会看到邻近的内存出现在数组的末尾存储器内容。

+0

我认为你的意思是'split_size + pad_length'。很好的答案! :D – martianwars

+0

的确,我做到了。更新,谢谢! –

+0

工程就像一个魅力。非常感谢! – martianwars

下接近:

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,正如你所说的那样。

+0

这对于更大的数组是否有效? – martianwars

+1

可能它不会太坏,因为它只是切片,它会产生数据的视图,而不是副本。只要确保为其他维度添加':'s即可。 – acdr

这里列出的是与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]])