Disons que j'ai un dataframe comme celui-ci
import pandas as pd
df = pd.DataFrame([[1, 2, 1], [1, 3, 2], [4, 6, 3], [4, 3, 4], [5, 4, 5]], columns=['A', 'B', 'C'])
>> df
A B C
0 1 2 1
1 1 3 2
2 4 6 3
3 4 3 4
4 5 4 5
La table d'origine est plus compliquée avec plus de colonnes et de lignes.
Je veux obtenir la première ligne qui remplit certains critères. Exemples:
Mais, si aucune ligne ne remplit les critères, je souhaite obtenir la première après la trier par ordre décroissant selon A (ou les autres cas selon B, C, etc.)
J'ai pu le faire en itérant sur la base de données (je sais que craps: P). Donc, je préfère un moyen plus pythonique de le résoudre.
Ce tutoriel est très bon pour le tranchage de pandas. Assurez-vous de vérifier. Sur certains extraits ... Pour découper une image de données avec une condition, vous utilisez ce format:
>>> df[condition]
Cela retournera une tranche de votre cadre de données que vous pouvez indexer à l'aide de iloc
. Voici vos exemples:
Obtenir la première ligne où A> 3 (retourne la ligne 2)
>>> df[df.A > 3].iloc[0]
A 4
B 6
C 3
Name: 2, dtype: int64
Si ce que vous voulez réellement est le numéro de ligne, plutôt que d'utiliser iloc
, ce serait df[df.A > 3].index[0]
.
Obtenez la première rangée où A> 4 ET B> 3:
>>> df[(df.A > 4) & (df.B > 3)].iloc[0]
A 5
B 4
C 5
Name: 4, dtype: int64
Obtenir la première ligne où A> 3 ET (B> 3 OR C> 2) (retourne la ligne 2)
>>> df[(df.A > 3) & ((df.B > 3) | (df.C > 2))].iloc[0]
A 4
B 6
C 3
Name: 2, dtype: int64
Maintenant, avec votre dernier cas, nous pouvons écrire une fonction qui gère le cas par défaut de retourner le cadre trié par ordre décroissant:
>>> def series_or_default(X, condition, default_col, ascending=False):
... sliced = X[condition]
... if sliced.shape[0] == 0:
... return X.sort_values(default_col, ascending=ascending).iloc[0]
... return sliced.iloc[0]
>>>
>>> series_or_default(df, df.A > 6, 'A')
A 5
B 4
C 5
Name: 4, dtype: int64
Comme prévu, il retourne à la ligne 4.
Pour les correspondances existantes, utilisez query
:
df.query(' A > 3' ).head(1)
Out[33]:
A B C
2 4 6 3
df.query(' A > 4 and B > 3' ).head(1)
Out[34]:
A B C
4 5 4 5
df.query(' A > 3 and (B > 3 or C > 2)' ).head(1)
Out[35]:
A B C
2 4 6 3