Python numpy take can';使用切片的t索引

Python numpy take can';使用切片的t索引,python,arrays,numpy,slice,Python,Arrays,Numpy,Slice,根据numpy的文件 它与“花式”索引(使用数组索引数组)的功能相同。但是,如果需要沿给定轴的元素,则可以更容易地使用它 但是,与“花式”或常规numpy索引不同,似乎不支持使用切片作为索引: In [319]: A = np.arange(20).reshape(4, 5) In [320]: A[..., 1:4] Out[320]: array([[ 1, 2, 3], [ 6, 7, 8], [11, 12, 13], [16, 17

根据numpy的文件 它与“花式”索引(使用数组索引数组)的功能相同。但是,如果需要沿给定轴的元素,则可以更容易地使用它

但是,与“花式”或常规numpy索引不同,似乎不支持使用切片作为索引:

In [319]: A = np.arange(20).reshape(4, 5)

In [320]: A[..., 1:4]
Out[320]: 
array([[ 1,  2,  3],
       [ 6,  7,  8],
       [11, 12, 13],
       [16, 17, 18]])

In [321]: np.take(A, slice(1, 4), axis=-1)
TypeError: long() argument must be a string or a number, not 'slice'

使用仅在运行时已知的轴上的切片索引数组的最佳方法是什么?

我认为您的意思是:

In [566]: np.take(A, slice(1,4))
...
TypeError: int() argument must be a string or a number, not 'slice'
但是

就像
A[1:4]

np.insert
np.apply\u沿\u轴
这样的函数通过构造可能包括标量、切片和数组的索引元组来实现通用性

ind = tuple([slice(1,4)])  # ndim terms to match array
A[ind]
np.tensordot
是使用
np.transpose
将动作轴移动到末端的示例(供
np.dot
使用)

另一个技巧是通过重塑将所有“多余”轴折叠为一个。之后再重新塑形

根据take的numpy文档,它与“花式”索引(使用数组索引数组)的功能相同

np.take
的第二个参数必须类似于数组(数组、列表、元组等),而不是
切片
对象。您可以构造一个索引数组或列表来执行所需的切片:

a = np.arange(24).reshape(2, 3, 4)

np.take(a, slice(1, 4, 2), 2)
# TypeError: long() argument must be a string or a number, not 'slice'

np.take(a, range(1, 4, 2), 2)
# array([[[ 1,  3],
#         [ 5,  7],
#         [ 9, 11]],

#        [[13, 15],
#         [17, 19],
#         [21, 23]]])
使用仅在运行时已知的轴上的切片索引数组的最佳方法是什么

我通常喜欢做的是使用将要索引的轴设置为第一个轴,进行索引,然后将其回滚到其原始位置

例如,假设我想要一个三维阵列沿其第三轴的奇数切片:

sliced1 = a[:, :, 1::2]
如果我想在运行时指定要切片的轴,我可以这样做:

n = 2    # axis to slice along

sliced2 = np.rollaxis(np.rollaxis(a, n, 0)[1::2], 0, n + 1)

assert np.all(sliced1 == sliced2)
要稍微打开一个衬里,请执行以下操作:

# roll the nth axis to the 0th position
np.rollaxis(a, n, 0)

# index odd-numbered slices along the 0th axis
np.rollaxis(a, n, 0)[1::2]

# roll the 0th axis back so that it lies before position n + 1 (note the '+ 1'!)
np.rollaxis(np.rollaxis(a, n, 0)[1::2], 0, n + 1)

最有效的方法似乎是
A[(切片(无),)*axis+(切片(1,4),)]


使用
np.r
是一个很好的紧凑解决方案。但是,请记住将停止索引的
None
替换为
A.shape[axis]
;并相应地处理负指数。从
np.rollaxis
:“此函数仍然支持向后兼容,但您应该更喜欢moveaxis。moveaxis函数是在NumPy 1.11中添加的。”如果您改用
np.moveaxis
,您不需要在答案中添加令人困惑的
+1
。这是以编程方式使用
\uuuu getitem\uuuu
# roll the nth axis to the 0th position
np.rollaxis(a, n, 0)

# index odd-numbered slices along the 0th axis
np.rollaxis(a, n, 0)[1::2]

# roll the 0th axis back so that it lies before position n + 1 (note the '+ 1'!)
np.rollaxis(np.rollaxis(a, n, 0)[1::2], 0, n + 1)
In [19]: import numpy as np
    ...: x = np.random.normal(0, 1, (50, 50, 50))
    ...: s = slice(10, 20)
    ...: axis = 2
    ...: 
    ...: 

In [20]: timeit np.rollaxis(np.rollaxis(x, axis, 0)[s], 0, axis + 1)
2.32 µs ± 15.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [21]: timeit x.take(np.arange(x.shape[axis])[s], axis)
28.5 µs ± 38.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [22]: timeit x[(slice(None),) * axis + (s,)]
321 ns ± 0.341 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)