跳过 numpy 数组的第 n 个索引
Skip every nth index of numpy array
为了进行 K 折验证,我想使用 slice 一个 numpy 数组,以便制作原始数组的视图,但删除每个第 n 个元素。
例如:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
如果n = 4
那么结果会是
[1, 2, 4, 5, 6, 8, 9]
注意:需要 numpy 是因为它被用于依赖关系固定的机器学习任务。
方法 #1 modulus
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])
使用 masking
的方法 #2:作为 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])
使用 NumPy array strides
的方法 #3:作为 view
的要求
您可以使用 np.lib.stride_tricks.as_strided
创建这样的视图,因为输入数组的长度是 n
的倍数。如果它不是倍数,它仍然可以工作,但不是安全的做法,因为我们会超出为输入数组分配的内存。请注意,这样创建的视图将是 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])
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])
我找到的最巧妙的答案是使用 delete,i
是您要跳过的第 n 个索引:
del list[i-1::i]
示例:
In [1]: a = list([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [2]: del a[4-1::4]
In [3]: print(a)
Out[3]: [0, 1, 2, 4, 5, 6, 8, 9]
如果您还想跳过第一个值,请使用 a[1:]
。
为了进行 K 折验证,我想使用 slice 一个 numpy 数组,以便制作原始数组的视图,但删除每个第 n 个元素。
例如:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
如果n = 4
那么结果会是
[1, 2, 4, 5, 6, 8, 9]
注意:需要 numpy 是因为它被用于依赖关系固定的机器学习任务。
方法 #1 modulus
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])
使用 masking
的方法 #2:作为 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])
使用 NumPy array strides
的方法 #3:作为 view
您可以使用 np.lib.stride_tricks.as_strided
创建这样的视图,因为输入数组的长度是 n
的倍数。如果它不是倍数,它仍然可以工作,但不是安全的做法,因为我们会超出为输入数组分配的内存。请注意,这样创建的视图将是 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])
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])
我找到的最巧妙的答案是使用 delete,i
是您要跳过的第 n 个索引:
del list[i-1::i]
示例:
In [1]: a = list([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [2]: del a[4-1::4]
In [3]: print(a)
Out[3]: [0, 1, 2, 4, 5, 6, 8, 9]
如果您还想跳过第一个值,请使用 a[1:]
。