Python 使用沿一个轴应用的argmin索引对多维数组进行索引

Python 使用沿一个轴应用的argmin索引对多维数组进行索引,python,numpy,Python,Numpy,我有两个多维数组,假设x和y都是5维的,我想求x的值,其中y的最后一个分量是极小值。 为了找到索引,我只使用I=argminy,axis=-1,这将返回一个4维索引数组。我应该如何找到这些索引的x值?某种x[I] 方法1:基本上扩展到5D情况。为了方便起见,我们可以使用开放范围数组,然后执行高级索引,如下所示- d0,d1,d2,d3,d4 = x.shape s0,s1,s2,s3 = np.ogrid[:d0,:d1,:d2,:d3] ymin = y[s0,s1,s2,s3,I] xmin

我有两个多维数组,假设x和y都是5维的,我想求x的值,其中y的最后一个分量是极小值。 为了找到索引,我只使用I=argminy,axis=-1,这将返回一个4维索引数组。我应该如何找到这些索引的x值?某种x[I]

方法1:基本上扩展到5D情况。为了方便起见,我们可以使用开放范围数组,然后执行高级索引,如下所示-

d0,d1,d2,d3,d4 = x.shape
s0,s1,s2,s3 = np.ogrid[:d0,:d1,:d2,:d3]
ymin = y[s0,s1,s2,s3,I]
xmin = x[s0,s1,s2,s3,I]
方法2:通过将前两个步骤与合并,我们可以将其缩短一点,因此有一个通用函数来处理通用维数的n数组-

indxs = np.ix_(*[np.arange(i) for i in x.shape[:-1]]) + (I,)
ymin = y[indxs]
xmin = x[indxs]
让我们使用一些样本随机值数组,通过直接计算沿最后一个轴的最小值y.minaxis=-1,即y.min-1进行验证,并将其与建议代码中的索引值ymin进行比较-

In [117]: x = np.random.randint(0,9,(3,4,5,6,7))
     ...: y = np.random.randint(0,9,(3,4,5,6,7))
     ...: I = np.argmin(y,axis=-1)
     ...: 

In [118]: d0,d1,d2,d3,d4 = x.shape
     ...: s0,s1,s2,s3 = np.ogrid[:d0,:d1,:d2,:d3]
     ...: ymin = y[s0,s1,s2,s3,I]
     ...: xmin = x[s0,s1,s2,s3,I]
     ...: 

In [119]: np.allclose( y.min(-1), ymin)
Out[119]: True

In [120]: indxs = np.ix_(*[np.arange(i) for i in x.shape[:-1]]) + (I,)
     ...: ymin = y[indxs]
     ...: xmin = x[indxs]
     ...: 

In [121]: np.allclose( y.min(-1), ymin)
Out[121]: True
将argmin与1或2d数组一起使用相当简单,但与3或更多数组一起使用时,映射更难理解:

In [332]: y=np.arange(24)
In [333]: np.random.shuffle(y)
In [334]: y=y.reshape(2,3,4)
In [335]: y
Out[335]: 
array([[[19, 12,  9, 21],
        [ 8, 13, 20, 17],
        [22, 11,  5,  1]],

       [[ 7,  2, 23, 16],
        [ 0, 10,  6,  4],
        [14, 18, 15,  3]]])

In [338]: I = np.argmin(y, axis=-1)
In [339]: I
Out[339]: 
array([[2, 0, 3],
       [1, 0, 3]], dtype=int32)
In [340]: np.min(y, axis=-1)
Out[340]: 
array([[9, 8, 1],
       [2, 0, 3]])
结果是2,3,每个平面/行一个索引

I[0,0]表示y[I,j,I[I,j]]是I,j行中的最小值

所以我们需要一种生成i,j配对的方法

或者将其缩短为:

In [350]: y[i,j,I]
Out[350]: 
array([[9, 8, 1],
       [2, 0, 3]])
即使使用2d,方法也相同:

In [360]: z=y[:,:,1]
In [361]: z
Out[361]: 
array([[12, 13, 11],
       [ 2, 10, 18]])
In [362]: idx=np.argmin(z, axis=-1)
In [363]: idx
Out[363]: array([2, 0], dtype=int32)
In [364]: z[[0,1], idx]       # index the 1st dim with range
Out[364]: array([11,  2])
使用mgrid可能会使流程更容易可视化:

In [378]: i,j =np.mgrid[0:2,0:3]
In [379]: i
Out[379]: 
array([[0, 0, 0],
       [1, 1, 1]])
In [380]: j
Out[380]: 
array([[0, 1, 2],
       [0, 1, 2]])
In [381]: y[i, j, I]
Out[381]: 
array([[9, 8, 1],
       [2, 0, 3]])
这里i和j是2,3个阵列,它们在形状上与i匹配。这3个数组一起从y中选择2,3个元素数组


ix_u和ogrid只生成等效的开放数组。

2d…4d?提供一些代码和一些研究,以便我们了解您所说的内容。我所拥有的是[87]shapex Out[87]中形状的x数组:6、10、10、5、50和相同尺寸的y数组。我想找到的是x的值,其中y的最后一个维度是最小的。我做的第一步是I=argminy,axis=-1,它返回一个索引数组。现在我想知道如何检查哪些x对应于这些indexes@gian9您能否提供x和y示例以及所需的输出?@Nuageux可能很难为5D数据生成。我想人们可以用一个随机形状的5D阵列来假设随机数据。但是这个过程没有保持维数,我错了吗?最好保持尺寸,以便轻松处理arrays@gian9要保持DIM,可以在末尾附加一个新轴:ymin[…,None]和xmin[…,None]。
In [378]: i,j =np.mgrid[0:2,0:3]
In [379]: i
Out[379]: 
array([[0, 0, 0],
       [1, 1, 1]])
In [380]: j
Out[380]: 
array([[0, 1, 2],
       [0, 1, 2]])
In [381]: y[i, j, I]
Out[381]: 
array([[9, 8, 1],
       [2, 0, 3]])