Trova la riga in cui i valori per la colonna sono massimi in un DataFrame panda


209

Come posso trovare la riga per cui il valore di una colonna specifica è massimo ?

df.max() mi darà il valore massimo per ogni colonna, non so come ottenere la riga corrispondente.


È possibile ottenere i primi 2 valori? anziché solo il massimo?
AsheKetchum,

5
È possibile utilizzare sort_valuese ottenere l'indice:df.sort_values('col', ascending=False)[:2].index
lazy1

2
lazy1: evita di ordinare inutilmente un'intera serie perché è O (N logN) in media, mentre trovare max / idxmax è solo O (N).
smci,

Risposte:


240

Usa la idxmaxfunzione Panda . È semplice:

>>> import pandas
>>> import numpy as np
>>> df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
>>> df
          A         B         C
0  1.232853 -1.979459 -0.573626
1  0.140767  0.394940  1.068890
2  0.742023  1.343977 -0.579745
3  2.125299 -0.649328 -0.211692
4 -0.187253  1.908618 -1.862934
>>> df['A'].argmax()
3
>>> df['B'].argmax()
4
>>> df['C'].argmax()
1
  • In alternativa puoi anche usare numpy.argmax, come numpy.argmax(df['A'])- fornisce la stessa cosa, e appare veloce almeno quanto idxmaxnelle osservazioni superficiali.

  • idxmax() restituisce etichette di indici, non numeri interi.

    • Esempio ': se hai valori di stringa come etichette di indice, come le righe da' a 'a' e ', potresti voler sapere che il massimo si verifica nella riga 4 (non nella riga' d ').
    • se vuoi la posizione intera di quella etichetta all'interno di quella Indexdevi ottenerla manualmente (il che può essere complicato ora che sono consentite etichette di riga duplicate).

NOTE STORICHE:

  • idxmax()era chiamato argmax()prima di 0.11
  • argmax è stato deprecato prima della 1.0.0 e rimosso completamente nella 1.0.0
  • a partire da Panda 0.16, argmaxesisteva ed eseguiva la stessa funzione (anche se sembrava funzionare più lentamente di idxmax).
    • argmaxLa funzione ha restituito la posizione intera all'interno dell'indice della posizione della riga dell'elemento massimo.
    • i panda sono passati all'utilizzo di etichette di riga anziché di indici interi. Gli indici interi posizionali erano molto comuni, più comuni delle etichette, specialmente nelle applicazioni in cui sono comuni etichette di riga duplicate.

Ad esempio, considera questo giocattolo DataFramecon un'etichetta di riga duplicata:

In [19]: dfrm
Out[19]: 
          A         B         C
a  0.143693  0.653810  0.586007
b  0.623582  0.312903  0.919076
c  0.165438  0.889809  0.000967
d  0.308245  0.787776  0.571195
e  0.870068  0.935626  0.606911
f  0.037602  0.855193  0.728495
g  0.605366  0.338105  0.696460
h  0.000000  0.090814  0.963927
i  0.688343  0.188468  0.352213
i  0.879000  0.105039  0.900260

In [20]: dfrm['A'].idxmax()
Out[20]: 'i'

In [21]: dfrm.iloc[dfrm['A'].idxmax()]  # .ix instead of .iloc in older versions of pandas
Out[21]: 
          A         B         C
i  0.688343  0.188468  0.352213
i  0.879000  0.105039  0.900260

Quindi qui un ingenuo uso di idxmaxnon è sufficiente, mentre la vecchia forma di argmaxfornirebbe correttamente la posizione posizionale della riga massima (in questo caso, posizione 9).

Questo è esattamente uno di quei cattivi tipi di comportamenti inclini ai bug in linguaggi tipicamente dinamici che rendono questo tipo di cose così sfortunate e che vale la pena battere un cavallo morto. Se stai scrivendo codice di sistema e il tuo sistema viene improvvisamente utilizzato su alcuni set di dati che non vengono puliti correttamente prima di essere uniti, è molto facile finire con etichette di riga duplicate, in particolare etichette di stringa come un identificatore CUSIP o SEDOL per attività finanziarie. Non è possibile utilizzare facilmente il sistema dei tipi per aiutarti e potresti non essere in grado di applicare l'univocità sull'indice senza incorrere in dati inaspettatamente mancanti.

Quindi rimani con la speranza che i tuoi test unitari coprano tutto (non lo hanno fatto, o più probabilmente nessuno ha scritto alcun test) - altrimenti (molto probabilmente) rimani solo in attesa di vedere se ti capita di entrare in questo errore in fase di esecuzione, nel qual caso probabilmente si deve andare cadere numero di ore vale la pena di lavoro dal database si erano l'output risultati, sbattere la testa contro il muro in IPython cercando di riprodurre manualmente il problema, finalmente capire che è perché idxmaxpuò solo segnala l' etichetta della riga massima, e poi rimarrai deluso dal fatto che nessuna funzione standard ottiene automaticamente le posizioni della riga massima per te, scrivendo tu stesso un'implementazione con errori, modificando il codice e pregando di non incorrere nuovamente nel problema.


13
Sulla base del penultimo commento, sembra argmine argmaxrimarrà parte di DataFramee la differenza è solo se si desidera l'indice o l'etichetta. idxmaxti darà l'etichetta della posizione in cui si verifica un massimo. argmaxti darà l'intero indice stesso.
ely,

4
Le informazioni fornite per spiegare la differenza tra argmaxe idxmaxe come evitare bug con indice duplicato sono state fantastiche! Non me ne sono accorto finché non ho letto il tuo commento nell'altra risposta. Grazie!
tupan,

Per quanto riguarda l'uso che vorresti implementare, Panda 0.24.1 indica quanto segue: 'il comportamento di argmaxsarà corretto per restituire il massimo posizionale in futuro. Per ora, utilizza series.values.argmaxo np.argmax(np.array(values))per ottenere la posizione della riga massima ".
Sam,

1
allo stesso modo, il .ixmetodo del secondo esempio è stato rinominato in.iloc
Ma0

se la tua colonna contiene solo valori nan, questo comporterà TypeError
Max Segal

77

Potresti anche provare idxmax:

In [5]: df = pandas.DataFrame(np.random.randn(10,3),columns=['A','B','C'])

In [6]: df
Out[6]: 
          A         B         C
0  2.001289  0.482561  1.579985
1 -0.991646 -0.387835  1.320236
2  0.143826 -1.096889  1.486508
3 -0.193056 -0.499020  1.536540
4 -2.083647 -3.074591  0.175772
5 -0.186138 -1.949731  0.287432
6 -0.480790 -1.771560 -0.930234
7  0.227383 -0.278253  2.102004
8 -0.002592  1.434192 -1.624915
9  0.404911 -2.167599 -0.452900

In [7]: df.idxmax()
Out[7]: 
A    0
B    8
C    7

per esempio

In [8]: df.loc[df['A'].idxmax()]
Out[8]: 
A    2.001289
B    0.482561
C    1.579985

Grazie Wes. Documentazione per idxmax () qui: pandas.pydata.org/pandas-docs/dev/generated/…
Will

df.ix[df['A'].idxmax()].valuesper afferrare l'array che volevo. funziona ancora.
Yojimbo,

2
Si noti che è necessario fare attenzione cercando di utilizzare l'output di idxmaxcome alimentatore ixo loccome mezzo per suddividere i dati e / o ottenere la posizione posizionale della riga massima. Perché puoi avere duplicati nel Index- vedi l'aggiornamento alla mia risposta per un esempio.
ely,

25

Entrambe le risposte sopra restituiranno un solo indice se ci sono più righe che accettano il valore massimo. Se vuoi tutte le righe, sembra che non ci sia una funzione. Ma non è difficile da fare. Di seguito è riportato un esempio di serie; lo stesso può essere fatto per DataFrame:

In [1]: from pandas import Series, DataFrame

In [2]: s=Series([2,4,4,3],index=['a','b','c','d'])

In [3]: s.idxmax()
Out[3]: 'b'

In [4]: s[s==s.max()]
Out[4]: 
b    4
c    4
dtype: int64

10
Grazie! versione per DataFrame:df[df['A'] == df['A'].max()]
Dennis Golomazov,

Questa è la risposta effettivamente corretta (la versione DataFrame).
gented

12
df.iloc[df['columnX'].argmax()]

argmax()fornirebbe l'indice corrispondente al valore massimo per columnX. ilocpuò essere utilizzato per ottenere la riga del DataFrame df per questo indice.


4

La soluzione diretta ".argmax ()" non funziona per me.

L'esempio precedente fornito da @ely

>>> import pandas
>>> import numpy as np
>>> df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
>>> df
      A         B         C
0  1.232853 -1.979459 -0.573626
1  0.140767  0.394940  1.068890
2  0.742023  1.343977 -0.579745
3  2.125299 -0.649328 -0.211692
4 -0.187253  1.908618 -1.862934
>>> df['A'].argmax()
3
>>> df['B'].argmax()
4
>>> df['C'].argmax()
1

restituisce il seguente messaggio:

FutureWarning: 'argmax' is deprecated, use 'idxmax' instead. The behavior of 'argmax' 
will be corrected to return the positional maximum in the future.
Use 'series.values.argmax' to get the position of the maximum now.

In modo che la mia soluzione sia:

df['A'].values.argmax()

2
mx.iloc[0].idxmax()

Questa riga di codice ti darà come trovare il valore massimo da una riga nel frame di dati, qui mxè il frame di dati e iloc[0]indica il 0 ° indice.


1

La idmaxdel dataframe restituisce l'indice etichetta della riga con il valore massimo e il comportamento argmaxdipende dalla versione pandas(al momento restituisce un avvertimento). Se si desidera utilizzare l' indice di posizione , è possibile effettuare le seguenti operazioni:

max_row = df['A'].values.argmax()

o

import numpy as np
max_row = np.argmax(df['A'].values)

Si noti che se si utilizza np.argmax(df['A'])si comporta come df['A'].argmax().

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.