Comment puis-je trouver la ligne pour laquelle la valeur d'une colonne spécifique est maximum ?
df.max()
me donnera la valeur maximale pour chaque colonne, je ne sais pas comment obtenir la ligne correspondante.
Comment puis-je trouver la ligne pour laquelle la valeur d'une colonne spécifique est maximum ?
df.max()
me donnera la valeur maximale pour chaque colonne, je ne sais pas comment obtenir la ligne correspondante.
Utilisez les pandas idxmax
fonction. C'est simple :
>>> 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
Vous pouvez également utiliser numpy.argmax
tels que numpy.argmax(df['A'])
-- il fournit la même chose, et apparaît au moins aussi rapidement que idxmax
dans des observations superficielles.
idxmax()
renvoie des étiquettes d'indices, et non des entiers.
Index
vous devez l'obtenir manuellement (ce qui peut être délicat maintenant que les étiquettes de ligne dupliquées sont autorisées).NOTES HISTORIQUES :
idxmax()
s'appelait autrefois argmax()
avant 0,11
argmax
a été déprécié avant la version 1.0.0 et entièrement supprimé dans la version 1.0.0.argmax
existaient et remplissaient la même fonction (bien qu'ils semblaient fonctionner plus lentement qu'auparavant). idxmax
).
argmax
a renvoyé le position entière dans l'index de l'emplacement de la ligne de l'élément maximal.Par exemple, considérez ce jouet DataFrame
avec une étiquette de ligne dupliquée :
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
Donc, ici, une utilisation naïve de idxmax
n'est pas suffisante, alors que l'ancienne forme de argmax
fournirait correctement le positionnel emplacement de la ligne max (dans ce cas, la position 9).
C'est exactement l'un de ces types de comportements susceptibles d'entraîner des bogues dans les langages typés dynamiquement qui rend ce genre de choses si malheureux, et qui vaut la peine de battre un cheval mort. Si vous écrivez du code système et que votre système est soudainement utilisé sur des ensembles de données qui n'ont pas été nettoyés correctement avant d'être joints, il est très facile de se retrouver avec des étiquettes de ligne en double, en particulier des étiquettes de chaîne comme un identifiant CUSIP ou SEDOL pour les actifs financiers. Vous ne pouvez pas facilement utiliser le système de type pour vous aider, et vous ne pourrez peut-être pas faire respecter l'unicité de l'index sans vous retrouver avec des données manquantes inattendues.
Il ne vous reste plus qu'à espérer que vos tests unitaires couvrent tout (ce n'est pas le cas, ou plus vraisemblablement personne n'a écrit de tests) -- sinon (c'est le plus probable), il ne vous reste plus qu'à attendre de voir si vous tombez sur cette erreur au moment de l'exécution, auquel cas vous devrez probablement abandonner plusieurs heures de travail depuis la base de données vers laquelle vous sortiez les résultats, vous frapper la tête contre le mur dans IPython en essayant de reproduire manuellement le problème, pour finalement découvrir que c'est parce que idxmax
peut uniquement signaler le étiquette de la rangée max, et ensuite être déçu qu'aucune fonction standard n'obtienne automatiquement la postes de la ligne max pour vous, en écrivant vous-même une implémentation boguée, en modifiant le code et en priant pour ne plus rencontrer le problème.
En se basant sur l'avant-dernier commentaire, on dirait que argmin
et argmax
fera toujours partie de DataFrame
et la différence est juste de savoir si vous voulez l'index ou l'étiquette. idxmax
vous donnera l'étiquette de l'endroit où se produit un maximum. argmax
vous donnera l'indice entier lui-même.
Les informations fournies pour expliquer la différence entre argmax
et idxmax
et comment éviter les bugs avec les index dupliqués était génial ! Je n'avais pas remarqué cela avant de lire votre commentaire dans l'autre réponse. Merci !
En ce qui concerne l'utilisation que vous souhaitez mettre en œuvre, Pandas 0.24.1 indique ce qui suit : "le comportement de argmax
sera corrigé pour retourner le maximum positionnel dans le futur. Pour l'instant, utilisez series.values.argmax
ou np.argmax(np.array(values))
pour obtenir la position de la rangée maximale.
Vous pouvez également essayer 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
par exemple
In [8]: df.loc[df['A'].idxmax()]
Out[8]:
A 2.001289
B 0.482561
C 1.579985
df.ix[df['A'].idxmax()].values
pour récupérer le tableau que je voulais. Ça marche toujours.
Notez que vous devez être prudent en essayant d'utiliser la sortie de idxmax
pour alimenter les ix
ou loc
comme moyen de subdiviser les données et/ou d'obtenir l'emplacement de la rangée maximale. Comme il peut y avoir des doublons dans le fichier Index
- voir la mise à jour de ma réponse pour un exemple.
Les deux réponses ci-dessus ne renvoient qu'un seul index s'il y a plusieurs lignes qui prennent la valeur maximale. Si vous voulez toutes les lignes, il ne semble pas y avoir de fonction. Mais ce n'est pas difficile à faire. Vous trouverez ci-dessous un exemple pour les séries ; la même chose peut être faite pour les 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
Une solution plus compacte et plus lisible utilisant query() c'est comme ça :
import pandas as pd
df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
print(df)
# find row with maximum A
df.query('A == A.max()')
Il renvoie également un DataFrame au lieu d'une série, ce qui serait pratique pour certains cas d'utilisation.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
Est-il possible d'obtenir les deux valeurs les plus élevées au lieu de la valeur maximale ?
9 votes
Vous pouvez utiliser
sort_values
et obtenir l'index :df.sort_values('col', ascending=False)[:2].index
8 votes
Paresseux1 : éviter de trier inutilement une série entière parce que c'est O(N logN) en moyenne, alors que trouver max/idxmax est seulement O(N).
0 votes
@AsheKetchum avez-vous obtenu une réponse à cette question ?