通过保留有关原始索引的信息对 ndarrays 进行排序
Order the min over ndarrays by keeping information about the original indexes
考虑使用形状为 (10,N,M)
.
的 numpy.ndarray
D1
我想构建一个形状为 (N*M,3)
的新 ndarray O1。这样:
- 每个元素都是一个三元组,标识一个元素在 D1 上的索引
- 索引按照D1中相应字段的值排序
- 对于每个
0≤i≤N
,0≤j≤M
仅考虑超过 10 个维度的最小元素。
让我们考虑一个使用 2 而不是 10 的小示例以及部分实现我的目标的当前方法:
>>> d1 = np.random.randint(20, size=2*3*3).reshape(2,3,3)
array([[[ 2, 6, 18],
[18, 18, 10],
[ 2, 3, 1]],
[[11, 3, 14],
[12, 14, 18],
[ 6, 8, 19]]])
>>> d2 = np.amin(d1, axis=0)
array([[ 2, 3, 14],
[12, 14, 10],
[ 2, 3, 1]])
>>> o1 = np.dstack(np.unravel_index(np.argsort(d2.ravel()), d2.shape))
array([[[2, 2],
[0, 0],
[2, 0],
[0, 1],
[2, 1],
[1, 2],
[1, 0],
[0, 2],
[1, 1]]])
通过这种方式,我获得了关于 2 维的元素的最小索引,但我丢失了有关 D1 中初始索引的信息。
在这种情况下预期的输出应该是:
array([[[0, 2, 2],
[0, 0, 0],
[0, 2, 0],
[1, 0, 1],
[0, 2, 1],
[0, 1, 2],
[1, 1, 0],
[1, 0, 2],
[1, 1, 1]]])
结构化数组是同时处理索引和最小值的便捷方式:
M, N = d1.shape[1:]
mi, ni = np.ogrid[:M, :N]
data = np.empty((M, N), [('coords', np.intp, 3), ('min', d1.dtype)])
data['coords'][..., 0] = mi
data['coords'][..., 1] = ni
data['coords'][..., 2] = np.argmin(d1, axis=0)
data['min'] = np.min(d1, axis=0)
data = data.ravel() # collapse (M, N) to (M*N,)
data_sorted = data[np.argsort(data['min'])]
o1 = data_sorted['coords']
但您也可以通过代码轻松到达那里:
d2 = np.min(d1, axis=0)
arg_d2 = np.argmin(d1, axis=0)
order = np.argsort(d2.ravel())
mi, ni = np.unravel_index(order, d2.shape)
o1 = np.stack((mi, ni, arg_d2.ravel()[order]), axis=-1) # dstack but faster
考虑使用形状为 (10,N,M)
.
的 numpy.ndarray
D1
我想构建一个形状为 (N*M,3)
的新 ndarray O1。这样:
- 每个元素都是一个三元组,标识一个元素在 D1 上的索引
- 索引按照D1中相应字段的值排序
- 对于每个
0≤i≤N
,0≤j≤M
仅考虑超过 10 个维度的最小元素。
让我们考虑一个使用 2 而不是 10 的小示例以及部分实现我的目标的当前方法:
>>> d1 = np.random.randint(20, size=2*3*3).reshape(2,3,3)
array([[[ 2, 6, 18],
[18, 18, 10],
[ 2, 3, 1]],
[[11, 3, 14],
[12, 14, 18],
[ 6, 8, 19]]])
>>> d2 = np.amin(d1, axis=0)
array([[ 2, 3, 14],
[12, 14, 10],
[ 2, 3, 1]])
>>> o1 = np.dstack(np.unravel_index(np.argsort(d2.ravel()), d2.shape))
array([[[2, 2],
[0, 0],
[2, 0],
[0, 1],
[2, 1],
[1, 2],
[1, 0],
[0, 2],
[1, 1]]])
通过这种方式,我获得了关于 2 维的元素的最小索引,但我丢失了有关 D1 中初始索引的信息。
在这种情况下预期的输出应该是:
array([[[0, 2, 2],
[0, 0, 0],
[0, 2, 0],
[1, 0, 1],
[0, 2, 1],
[0, 1, 2],
[1, 1, 0],
[1, 0, 2],
[1, 1, 1]]])
结构化数组是同时处理索引和最小值的便捷方式:
M, N = d1.shape[1:]
mi, ni = np.ogrid[:M, :N]
data = np.empty((M, N), [('coords', np.intp, 3), ('min', d1.dtype)])
data['coords'][..., 0] = mi
data['coords'][..., 1] = ni
data['coords'][..., 2] = np.argmin(d1, axis=0)
data['min'] = np.min(d1, axis=0)
data = data.ravel() # collapse (M, N) to (M*N,)
data_sorted = data[np.argsort(data['min'])]
o1 = data_sorted['coords']
但您也可以通过代码轻松到达那里:
d2 = np.min(d1, axis=0)
arg_d2 = np.argmin(d1, axis=0)
order = np.argsort(d2.ravel())
mi, ni = np.unravel_index(order, d2.shape)
o1 = np.stack((mi, ni, arg_d2.ravel()[order]), axis=-1) # dstack but faster