提问者:小点点

使用来自另一个数组的索引对numpy数组进行切片


我简直要疯了,试图根据来自另一个数组的值对一个2D数组进行切片:

# array of integer values:
aa = np.random.randint(500, 600, size=(5,5)

array([[574, 550, 548, 545, 551],
       [547, 539, 539, 502, 528],
       [503, 530, 582, 567, 505],
       [590, 504, 510, 578, 525],
       [530, 548, 501, 580, 583]])

# array of indices:
ab = np.random.randint(4, size=(5,5))

array([[3, 0, 2, 1, 1],
       [3, 2, 2, 1, 3],
       [0, 3, 1, 2, 0],
       [1, 2, 3, 1, 3],
       [3, 0, 1, 1, 0]])

我要返回的是aa的2D子数组,其中ab是1。 但我能得到的最接近的结果是:

aa[ab==1]

array([545, 551, 502, 582, 590, 578, 501, 580])

我总是得到一维数组作为输出。。。 如何获得与原始数组相同维度的输出数组?

编辑:对不起,我应该指定预期输出:

array([[545, 551],
       [502],
       [582],
       [590, 578],
       [501, 580]])

我还为索引数组ab选了一个很差的例子,它每行总是有相同数量的1-所以输出数组的维数为(5,2)。


共1个答案

匿名用户

就我所知和常识而言,numpy不支持由不同形状的数字组成的2D数组(每行一个或两个数字)。 如果尝试实例化预期结果的数组,则会遇到以下问题:

In[23]: np.array([[545, 551],
   [502],
   [582],
   [590, 578],
   [501, 580]])
Out[23]: 
array([list([545, 551]), list([502]), list([582]), list([590, 578]),
   list([501, 580])], dtype=object) # Note the data type.

In[24]: np.array([[545, 551],
   [502],
   [582],
   [590, 578],
   [501, 580]],dtype=float) # Force float.
TypeError: float() argument must be a string or a number, not 'list'

如果您确信ab中的1s的数量始终相等且已知,则可以执行以下操作:

In[2]: aa = np.array([[574, 550, 548, 545, 551],
   [547, 539, 539, 502, 528],
   [503, 530, 582, 567, 505],
   [590, 504, 510, 578, 525],
   [530, 548, 501, 580, 583]])

In[3]: ab = np.array([[3, 0, 2, 1, 1], # N.B. edited w.r.t. your example to have two 1s per row.
   [3, 1, 2, 1, 3],
   [0, 1, 1, 2, 0],
   [1, 2, 3, 1, 3],
   [3, 0, 1, 1, 0]])

In[4]: aa[ab==1].reshape((-1,2))
Out[4]: 
array([[545, 551],
   [539, 502],
   [530, 582],
   [590, 578],
   [501, 580]])

如果您事先不知道ab的每一行中有多少1s,则可以简单地执行以下操作:

In[5]: aa[ab==1].reshape((-1,sum(ab[0,:]==1)))
Out[5]: 
array([[545, 551],
   [539, 502],
   [530, 582],
   [590, 578],
   [501, 580]])

这回答了你的问题吗? 或者您正在寻找更像注释中建议的maskedarray的内容?