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]
21
demandé sur Alex Riley 2013-06-13 00:10:25

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])
30
répondu mg007 2013-06-13 07:38:31

Je pense que énumérer est à portée de main.

[input_array[enum, item] for enum, item in enumerate(select_id)]
2
répondu y4suyuki 2013-06-13 13:32:55

(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:

  1. Est-il un meilleur moyen d'obtenir le output_array de la input_array et select_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.
  2. 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.
2
répondu Nathan 2018-04-17 19:08:45

Que diriez-vous de:

[input_array[x,y] for x,y in zip(range(len(input_array[:,0])),select_id)]
0
répondu atomh33ls 2013-06-13 13:06:56