跳过numpy数组的每个第n个索引

时间:2016-12-02 10:08:07

标签: python numpy slice

为了进行K-fold验证,我想使用slice一个numpy数组,这样就可以生成原始数组的视图,但每次删除第n个元素。

例如:[0,1,2,3,4,5,6,7,8,9]

如果n = 4则结果为[1,2,4,5,6,8,9]

注意:numpy要求是由于这被用于机器学习分配,其中依赖关系是固定的。

2 个答案:

答案 0 :(得分:6)

modulus

的方法#1
a[np.mod(np.arange(a.size),4)!=0]

示例运行 -

In [255]: a
Out[255]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [256]: a[np.mod(np.arange(a.size),4)!=0]
Out[256]: array([1, 2, 3, 5, 6, 7, 9])

方法#2与masking:要求为view

考虑到视图要求,如果想要节省内存,我们可以存储等效的布尔数组,该数组在Linux系统上占用的内存少8倍。因此,这种基于掩模的方法就是这样 -

# Create mask
mask = np.ones(a.size, dtype=bool)
mask[::4] = 0

这是内存要求统计 -

In [311]: mask.itemsize
Out[311]: 1

In [312]: a.itemsize
Out[312]: 8

然后,我们可以使用布尔索引作为视图 -

In [313]: a
Out[313]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [314]: a[mask] = 10

In [315]: a
Out[315]: array([ 0, 10, 10, 10,  4, 10, 10, 10,  8, 10])

方法#3与NumPy array strides:要求为view

如果输入数组的长度是n的倍数,则可以使用np.lib.stride_tricks.as_strided创建此类视图。如果它不是一个倍数,它仍然可以工作,但不是一个安全的做法,因为我们将超出为输入数组分配的内存。请注意,这样创建的视图为2D

因此,获得这种观点的实现将是 -

def skipped_view(a, n):
    s = a.strides[0]
    strided = np.lib.stride_tricks.as_strided
    return strided(a,shape=((a.size+n-1)//n,n),strides=(n*s,s))[:,1:]

示例运行 -

In [50]: a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) # Input array

In [51]: a_out = skipped_view(a, 4)

In [52]: a_out
Out[52]: 
array([[ 1,  2,  3],
       [ 5,  6,  7],
       [ 9, 10, 11]])

In [53]: a_out[:] = 100 # Let's prove output is a view indeed

In [54]: a
Out[54]: array([  0, 100, 100, 100,   4, 100, 100, 100,   8, 100, 100, 100])

答案 1 :(得分:2)

numpy.delete

In [18]: arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [19]: arr = np.delete(arr, np.arange(0, arr.size, 4))

In [20]: arr
Out[20]: array([1, 2, 3, 5, 6, 7, 9])