将 numpy 花式索引与省略号混合
Mixing numpy fancy indexing with ellipsis
如何在 numpy 中将花式索引与 ...
相结合?
考虑一些测试数据:
# Some test data of high dimensionality
shape = (3,5,2,8)
data = np.arange(np.prod(shape)).reshape(shape)
也许我有一个索引元组。我无法在索引期间解压缩这些值:
# Arbitrary indices
indices = (0, 4)
# Try unpacking
data[*indices]
# >>> SyntaxError: invalid syntax
不用担心,如果我单独传递索引或将索引作为元组传递,我会得到相同的结果 — 很好!
np.all(data[indices[0], indices[1]] == data[indices])
# >>> True
所以不需要拆包,对吧? 相关问题似乎暗示如此。
Python's indexing already has built-in support for tuples in general [...] there is no need for iterator unpacking in indexing. Simply convert your iterator to a tuple
乍一看,它甚至似乎可以与奇特的索引一起使用:
# New arbitrary indices
new_indices = (np.array([0,1]), np.array([4,4]))
np.all(data[new_indices] == data[new_indices[0], new_indices[1]])
# >>> True
但是如果我尝试使用 ellipsis
它就会崩溃。例如,如果我想在尾随轴上进行花式索引:
# Passing unpacked values produces the desired result
data[..., new_indices[0], new_indices[1]] # shape=(3,5,2)
# Passing as a tuple does NOT produce the desired result
data[..., new_indices] # shape=(3,5,2,2,2)
当然如果我的数据是变维的,我就不能写..., new_indices[0], new_indices[1]
。所以看来在这种情况下实际上需要拆包。
好吧,也许我可以这样做:
data.T[indices[::-1]].T.shape # shape=(3,5,2)
感觉有点老套,但确实有效。除非我们想在引导轴和尾随轴上使用 ...
之间的奇特索引,否则我们似乎真的不走运:
# Some test data of even higher dimensionality
data_shape = (3,5,2,8,12,25)
data = np.arange(np.prod(data_shape)).reshape(data_shape)
index_A = (np.array([0,0,1]), np.array([0,2,1]))
index_B = (np.array([0,0,0]), np.array([1,1,1]))
# Desired result, shape=(3,2)
data[index_A[0], index_A[1], ..., index_B[0], index_B[1]]
# Without unpacking, shape=(2,3,5,2,8)
data[index_A, ..., index_B]
也许这是一个边缘案例,但似乎应该有办法做到这一点。怎么样?
P.S。无论如何,为什么在这种情况下可迭代解包会引发 SyntaxError?
tuple
加入就可以了:
In [142]: data[(...,)+indices]
Out[142]:
array([[ 4, 20, 36, 52, 68],
[ 84, 100, 116, 132, 148],
[164, 180, 196, 212, 228]])
In [143]: data[...,0,4]
Out[143]:
array([[ 4, 20, 36, 52, 68],
[ 84, 100, 116, 132, 148],
[164, 180, 196, 212, 228]])
In [144]: (...,)+indices
Out[144]: (Ellipsis, 0, 4)
在元组内解包也可以:
data[(...,*indices)]
如何在 numpy 中将花式索引与 ...
相结合?
考虑一些测试数据:
# Some test data of high dimensionality
shape = (3,5,2,8)
data = np.arange(np.prod(shape)).reshape(shape)
也许我有一个索引元组。我无法在索引期间解压缩这些值:
# Arbitrary indices
indices = (0, 4)
# Try unpacking
data[*indices]
# >>> SyntaxError: invalid syntax
不用担心,如果我单独传递索引或将索引作为元组传递,我会得到相同的结果 — 很好!
np.all(data[indices[0], indices[1]] == data[indices])
# >>> True
所以不需要拆包,对吧?
Python's indexing already has built-in support for tuples in general [...] there is no need for iterator unpacking in indexing. Simply convert your iterator to a tuple
乍一看,它甚至似乎可以与奇特的索引一起使用:
# New arbitrary indices
new_indices = (np.array([0,1]), np.array([4,4]))
np.all(data[new_indices] == data[new_indices[0], new_indices[1]])
# >>> True
但是如果我尝试使用 ellipsis
它就会崩溃。例如,如果我想在尾随轴上进行花式索引:
# Passing unpacked values produces the desired result
data[..., new_indices[0], new_indices[1]] # shape=(3,5,2)
# Passing as a tuple does NOT produce the desired result
data[..., new_indices] # shape=(3,5,2,2,2)
当然如果我的数据是变维的,我就不能写..., new_indices[0], new_indices[1]
。所以看来在这种情况下实际上需要拆包。
好吧,也许我可以这样做:
data.T[indices[::-1]].T.shape # shape=(3,5,2)
感觉有点老套,但确实有效。除非我们想在引导轴和尾随轴上使用 ...
之间的奇特索引,否则我们似乎真的不走运:
# Some test data of even higher dimensionality
data_shape = (3,5,2,8,12,25)
data = np.arange(np.prod(data_shape)).reshape(data_shape)
index_A = (np.array([0,0,1]), np.array([0,2,1]))
index_B = (np.array([0,0,0]), np.array([1,1,1]))
# Desired result, shape=(3,2)
data[index_A[0], index_A[1], ..., index_B[0], index_B[1]]
# Without unpacking, shape=(2,3,5,2,8)
data[index_A, ..., index_B]
也许这是一个边缘案例,但似乎应该有办法做到这一点。怎么样?
P.S。无论如何,为什么在这种情况下可迭代解包会引发 SyntaxError?
tuple
加入就可以了:
In [142]: data[(...,)+indices]
Out[142]:
array([[ 4, 20, 36, 52, 68],
[ 84, 100, 116, 132, 148],
[164, 180, 196, 212, 228]])
In [143]: data[...,0,4]
Out[143]:
array([[ 4, 20, 36, 52, 68],
[ 84, 100, 116, 132, 148],
[164, 180, 196, 212, 228]])
In [144]: (...,)+indices
Out[144]: (Ellipsis, 0, 4)
在元组内解包也可以:
data[(...,*indices)]