Sélectionnez un élément dans chaque ligne D'un tableau Numpy par index de colonne
Existe-t-il un meilleur moyen d'obtenir le "output_array" à partir du "input_array" et du "select_id" ?
Peut-on se débarrasser de range( input_array.shape[0] )
?
>>> input_array = numpy.array( [ [3,14], [12, 5], [75, 50] ] )
>>> select_id = [0, 1, 1]
>>> print input_array
[[ 3 14]
[12 5]
[75 50]]
>>> output_array = input_array[ range( input_array.shape[0] ), select_id ]
>>> print output_array
[ 3 5 50]
4 réponses
, Vous pouvez choisir à partir de tableau à l'aide de numpy.choose
qui construit un tableau à partir d'un index de tableau (dans votre cas, select_id
) et un ensemble de tableaux (dans votre cas, input_array
) à choisir. Cependant, vous devrez peut-être d'abord transposer input_array
pour correspondre aux dimensions. La figure suivante montre un petit exemple:
In [101]: input_array
Out[101]:
array([[ 3, 14],
[12, 5],
[75, 50]])
In [102]: input_array.shape
Out[102]: (3, 2)
In [103]: select_id
Out[103]: [0, 1, 1]
In [104]: output_array = np.choose(select_id, input_array.T)
In [105]: output_array
Out[105]: array([ 3, 5, 50])
(parce que je ne peux pas poster cela comme un commentaire sur la réponse acceptée)
Notez que numpy.choose
ne fonctionne que si vous avez 32 choix ou moins (dans ce cas, la dimension de votre tableau le long de laquelle vous indexez doit être de taille 32 ou plus petite). De plus, la documentation pour numpy.choose
indique
Pour réduire le risque de mauvaise interprétation, même si les "abus" suivants sont nominalement soutenus, les choix ne devraient ni être, ni être considérés comme un seul array, c'est-à-dire que le conteneur de type séquence le plus externe doit être une liste ou un tuple.
Le PO demande:
- Est-il un meilleur moyen d'obtenir le
output_array
de lainput_array
etselect_id
?- je dirais que la façon dont vous avez initialement suggéré semble la meilleure de celles présentées ici. Il est facile à comprendre, s'adapte à de grands tableaux et est efficace.
- Peut-on se débarrasser de
range(input_array.shape[0])
?- oui, comme le montrent d'autres réponses, mais celle acceptée ne fonctionne pas en général aussi bien que ce que L'OP suggère déjà de faire.
Que diriez-vous de:
[input_array[x,y] for x,y in zip(range(len(input_array[:,0])),select_id)]