这里的广播顺序是什么?
What is the broadcasting order here?
鉴于以下情况:
polygons = np.array([
[[1, 0],
[1, 1],
[0, 0],
[0, 1]],
[[3, 2],
[2, 2],
[4, 4],
[2, 3]]])
sort_idx = np.array([
[2, 0, 1, 3],
[1, 0, 2, 3]])
polygons[sort_idx] #< The problematic part
预期输出为:
array([[[0, 0],
[1, 0],
[1, 1],
[0, 1]],
[[2, 2],
[3, 2],
[4, 4],
[2, 3]]])
我希望 polygons[sort_idx]
到 return polygons
的“已排序”行,排序顺序由 sort_idx
中的值给出。
polygons[0][sorted_idx[0]]
(以及 [1]
的等价物)给出了正确的值,但是 运行 polygons[sort_idx]
提出:
IndexError: index 2 is out of bounds for axis 0 with size 2
我估计这个问题与我不了解该操作的广播方式有关,但我真的不知道要搜索什么或如何表达这个问题。我看到类似的问题建议使用 np.take()
或 polygons[sort_idx,...]
,但两者都会引发相同的错误。我错过了什么?
使用np.take_along_axis
:
np.take_along_axis(polygons, sort_idx[..., None], 1)
Out[]:
array([[[0, 0],
[1, 0],
[1, 1],
[0, 1]],
[[2, 2],
[3, 2],
[4, 4],
[2, 3]]])
take_along_axis
应该 'streamline' 索引我们必须做(并且仍然可以做):
In [233]: polygons[np.arange(2)[:,None], sort_idx]
Out[233]:
array([[[0, 0],
[1, 0],
[1, 1],
[0, 1]],
[[2, 2],
[3, 2],
[4, 4],
[2, 3]]])
第一个维度索引是(2,1),然后是第二个(2,4),在前2个维度一起广播到select(2,4)(最后一个维度不变).
sort_idx
的值适用于第 2 个轴,即 4 号轴。 polygons[sort_idx]
将它们应用于第一个大小为 2 的维度,因此出现错误。
对第一个维度使用切片 returns 值太多,一个块。我们想要更像对角线的东西:
In [235]: polygons[:, sort_idx,:].shape
Out[235]: (2, 2, 4, 2)
所以是的,这是一个 broadcasting
问题。当使用多个索引数组时,我们要考虑它们如何 broadcast
相互对抗。适用与运算符相同的规则。
In [236]: np.array([10,100])[:,None]* sort_idx
Out[236]:
array([[ 20, 0, 10, 30],
[100, 0, 200, 300]])
鉴于以下情况:
polygons = np.array([
[[1, 0],
[1, 1],
[0, 0],
[0, 1]],
[[3, 2],
[2, 2],
[4, 4],
[2, 3]]])
sort_idx = np.array([
[2, 0, 1, 3],
[1, 0, 2, 3]])
polygons[sort_idx] #< The problematic part
预期输出为:
array([[[0, 0],
[1, 0],
[1, 1],
[0, 1]],
[[2, 2],
[3, 2],
[4, 4],
[2, 3]]])
我希望 polygons[sort_idx]
到 return polygons
的“已排序”行,排序顺序由 sort_idx
中的值给出。
polygons[0][sorted_idx[0]]
(以及 [1]
的等价物)给出了正确的值,但是 运行 polygons[sort_idx]
提出:
IndexError: index 2 is out of bounds for axis 0 with size 2
我估计这个问题与我不了解该操作的广播方式有关,但我真的不知道要搜索什么或如何表达这个问题。我看到类似的问题建议使用 np.take()
或 polygons[sort_idx,...]
,但两者都会引发相同的错误。我错过了什么?
使用np.take_along_axis
:
np.take_along_axis(polygons, sort_idx[..., None], 1)
Out[]:
array([[[0, 0],
[1, 0],
[1, 1],
[0, 1]],
[[2, 2],
[3, 2],
[4, 4],
[2, 3]]])
take_along_axis
应该 'streamline' 索引我们必须做(并且仍然可以做):
In [233]: polygons[np.arange(2)[:,None], sort_idx]
Out[233]:
array([[[0, 0],
[1, 0],
[1, 1],
[0, 1]],
[[2, 2],
[3, 2],
[4, 4],
[2, 3]]])
第一个维度索引是(2,1),然后是第二个(2,4),在前2个维度一起广播到select(2,4)(最后一个维度不变).
sort_idx
的值适用于第 2 个轴,即 4 号轴。 polygons[sort_idx]
将它们应用于第一个大小为 2 的维度,因此出现错误。
对第一个维度使用切片 returns 值太多,一个块。我们想要更像对角线的东西:
In [235]: polygons[:, sort_idx,:].shape
Out[235]: (2, 2, 4, 2)
所以是的,这是一个 broadcasting
问题。当使用多个索引数组时,我们要考虑它们如何 broadcast
相互对抗。适用与运算符相同的规则。
In [236]: np.array([10,100])[:,None]* sort_idx
Out[236]:
array([[ 20, 0, 10, 30],
[100, 0, 200, 300]])