np.ufunc.at 和 np.ix_ 的 Numpy 多维索引
Numpy multidimensional indexing for np.ufunc.at and np.ix_
我想知道如何从数组中获取索引并与另一个数组相乘。我有两个 4d 数组和一个 2d 索引数组:
base = np.ones((2, 3, 5, 5))
to_multiply = np.arange(120).reshape(2, 3, 4, 5)
index = np.array([[0, 2, 4, 2], [0, 3, 3, 2]])
index数组的行索引对应base的第1维,to_multiply,index数组的值对应base的第3维。我想根据索引从 base 中取出切片并乘以 to_multiply.
使用for循环和np.multiply.at(因为我可能有相同的索引)我可以通过以下方式实现它:
for i, x in enumerate(index):
np.multiply.at(base[i, :, :, :], np.s_[:, x, :], to_multiply[i, :, :, :])
以上的正确性可以通过以下方式验证:
to_multiply[0, 0, :, 0]
array([ 0, 5, 10, 15])
base[0, 0, :, 0]
array([ 0., 1., 75., 1., 10.])
但是,我想知道是否有使用np.multiply.at和np.ix_
的单行解决方案
我尝试使用 np.ix_ 但我对此很困惑,因为在这种情况下它是多维的。
ix_
无法完成。来自其文档:
This function takes N 1-D sequences and returns N outputs with N
dimensions each,
你的 index
是 2d。
然而,我们可以做等价的 'by-hand':
In [196]: np.multiply.at(base1, (np.arange(2)[:,None,None],np.arange(3)[:,None],index[:,None,:]), to_
...: multiply)
In [197]: np.allclose(base,base1)
Out[197]: True
目标是制作 3 个一起广播的数组以匹配 to_multiply
(最后一个尺寸 5 维除外)。
即 (2,1,1), (1,3,1) 和 (2,1,4) => (2,3,4)
In [199]: np.broadcast_arrays(np.arange(2)[:,None,None],np.arange(3)[:,None],index[:,None,:])
Out[199]:
[array([[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]]),
array([[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]],
[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]]]),
array([[[0, 2, 4, 2],
[0, 2, 4, 2],
[0, 2, 4, 2]],
[[0, 3, 3, 2],
[0, 3, 3, 2],
[0, 3, 3, 2]]])]
虽然我对自己想去的地方有一个大概的想法,但我必须先尝试很多想法。
我想知道如何从数组中获取索引并与另一个数组相乘。我有两个 4d 数组和一个 2d 索引数组:
base = np.ones((2, 3, 5, 5))
to_multiply = np.arange(120).reshape(2, 3, 4, 5)
index = np.array([[0, 2, 4, 2], [0, 3, 3, 2]])
index数组的行索引对应base的第1维,to_multiply,index数组的值对应base的第3维。我想根据索引从 base 中取出切片并乘以 to_multiply.
使用for循环和np.multiply.at(因为我可能有相同的索引)我可以通过以下方式实现它:
for i, x in enumerate(index):
np.multiply.at(base[i, :, :, :], np.s_[:, x, :], to_multiply[i, :, :, :])
以上的正确性可以通过以下方式验证:
to_multiply[0, 0, :, 0]
array([ 0, 5, 10, 15])
base[0, 0, :, 0]
array([ 0., 1., 75., 1., 10.])
但是,我想知道是否有使用np.multiply.at和np.ix_
的单行解决方案我尝试使用 np.ix_ 但我对此很困惑,因为在这种情况下它是多维的。
ix_
无法完成。来自其文档:
This function takes N 1-D sequences and returns N outputs with N dimensions each,
你的 index
是 2d。
然而,我们可以做等价的 'by-hand':
In [196]: np.multiply.at(base1, (np.arange(2)[:,None,None],np.arange(3)[:,None],index[:,None,:]), to_
...: multiply)
In [197]: np.allclose(base,base1)
Out[197]: True
目标是制作 3 个一起广播的数组以匹配 to_multiply
(最后一个尺寸 5 维除外)。
即 (2,1,1), (1,3,1) 和 (2,1,4) => (2,3,4)
In [199]: np.broadcast_arrays(np.arange(2)[:,None,None],np.arange(3)[:,None],index[:,None,:])
Out[199]:
[array([[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]]),
array([[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]],
[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]]]),
array([[[0, 2, 4, 2],
[0, 2, 4, 2],
[0, 2, 4, 2]],
[[0, 3, 3, 2],
[0, 3, 3, 2],
[0, 3, 3, 2]]])]
虽然我对自己想去的地方有一个大概的想法,但我必须先尝试很多想法。