如何从ndarray的列中索引元素,以使输出为列向量?

时间:2019-08-28 16:10:53

标签: python numpy indexing numpy-ndarray

我有一个nx2点数组,表示为ndarray。我想索引两个列向量之一的某些元素(索引也在ndarray中给出),以便输出是列向量。但是,如果索引数组仅包含一个索引,则应返回(1,)形的数组。

我已经尝试了以下操作,但未成功:

import numpy as np

points = np.array([[0, 1], [1, 1.5], [2.5, 0.5], [4, 1], [5, 2]])
index = np.array([0, 1, 2])

points[index, [0]] -> array([0. , 1. , 2.5]) -> shape (3,)
points[[index], 0] -> array([[0. , 1. , 2.5]]) -> shape (1, 3)
points[[index], [0]] -> array([[0. , 1. , 2.5]]) -> shape (1, 3)
points[index, 0, np.newaxis] -> array([[0. ], [1. ], [2.5]]) -> shape(3, 1) # desired

np.newaxis适用于这种情况,但是,如果索引数组仅包含一个值,则不能提供正确的形状:

import numpy as np

points = np.array([[0, 1], [1, 1.5], [2.5, 0.5], [4, 1], [5, 2]])
index = np.array([0])

points[index, 0, np.newaxis] -> array([[0.]]) -> shape (1, 1)
points[index, [0]] -> array([0.]) -> shape (1,) # desired

是否有可能对ndarray进行索引,以使输出在第一个示例中具有形状(3,1),在第二个示例中具有形状(1,),而无需根据索引数组的大小进行大小写区分?

在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

In [329]: points = np.array([[0, 1], [1, 1.5], [2.5, 0.5], [4, 1], [5, 2]]) 
     ...: index = np.array([0, 1, 2])  

我们可以选择3行:

In [330]: points[index,:]                                                                                    
Out[330]: 
array([[0. , 1. ],
       [1. , 1.5],
       [2.5, 0.5]])

但是,即使我们也选择一列,即使使用[0],结果也是1d。这是因为(3,)行索引是针对(1,)列索引广播的,结果是(3,):

In [331]: points[index,0]                                                                                    
Out[331]: array([0. , 1. , 2.5])
In [332]: points[index,[0]]                                                                                  
Out[332]: array([0. , 1. , 2.5])

如果使行索引为(3,1)形状,则结果也为(3,1):

In [333]: points[index[:,None],[0]]                                                                          
Out[333]: 
array([[0. ],
       [1. ],
       [2.5]])
In [334]: points[index[:,None],0]                                                                            
Out[334]: 
array([[0. ],
       [1. ],
       [2.5]])

如果使用行切片,则会得到相同的结果:

In [335]: points[0:3,[0]]                                                                                    
Out[335]: 
array([[0. ],
       [1. ],
       [2.5]])

使用[index]无济于事,因为它使行索引为(1,3)形状,结果为(1,3)。当然,您可以将其转置为(3,1)。

带有1个元素index

In [336]: index1 = np.array([0])                                                                             
In [337]: points[index1[:,None],0]                                                                           
Out[337]: array([[0.]])
In [338]: _.shape                                                                                            
Out[338]: (1, 1)
In [339]: points[index1,0]                                                                                   
Out[339]: array([0.])
In [340]: _.shape                                                                                            
Out[340]: (1,)

如果行索引是标量,而不是1d:

In [341]: index1 = np.array(0)                                                                               
In [342]: points[index1[:,None],0]                                                                           
...
IndexError: too many indices for array
In [343]: points[index1[...,None],0]        # use ... instead                                                                 
Out[343]: array([0.])
In [344]: points[index1, 0]     # scalar result                                                                             
Out[344]: 0.0

我认为分别处理np.array([0])情况需要进行if测试。至少我无法想到内置的numpy掩埋方式。

答案 1 :(得分:0)

我不确定我是否理解您的问题中的措辞,但似乎您似乎在使用ndarray.swapaxes方法(请参阅https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.swapaxes.html#numpy.ndarray.swapaxes

针对您的摘录:

points = np.array([[0, 1], [1, 1.5], [2.5, 0.5], [4, 1], [5, 2]])
swapped = points.swapaxes(0,1)
print(swapped)

给予

[[0.  1.  2.5 4.  5. ]
 [1.  1.5 0.5 1.  2. ]]