Obtenga la primera fila de dataframe en Python Pandas basado en criterios

Digamos que tengo un dataframe como este

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 ABC 0 1 2 1 1 1 3 2 2 4 6 3 3 4 3 4 4 5 4 5 

La tabla original es más complicada con más columnas y filas.

Quiero conseguir la primera fila que cumpla algunos criterios. Ejemplos:

  1. Obtener la primera fila donde A> 3 (devuelve la fila 2)
  2. Obtenga la primera fila donde A> 4 Y B> 3 (devuelve la fila 4)
  3. Obtenga la primera fila donde A> 3 Y (B> 3 O C> 2) (devuelve la fila 2)

Pero, si no hay ninguna fila que cumpla con los criterios específicos, quiero obtener la primera después de que simplemente la clasifique descendiendo por A (u otros casos por B, C, etc.)

  1. Obtenga la primera fila donde A> 6 (devuelve la fila 4 ordenándola por A desc y obtenga la primera)

Pude hacerlo iterando en el dataframe (sé que craps: P). Por eso, prefiero una forma más pythonica de resolverlo.

Este tutorial es muy bueno para cortar pandas. Asegúrate de comprobarlo. En algunos fragmentos … Para cortar un dataframe con una condición, use este formato:

 >>> df[condition] 

Esto devolverá una porción de su dataframe que puede indexar usando iloc . Aquí están sus ejemplos:

  1. Obtener la primera fila donde A> 3 (devuelve la fila 2)

     >>> df[df.A > 3].iloc[0] A 4 B 6 C 3 Name: 2, dtype: int64 

Si lo que realmente desea es el número de fila, en lugar de utilizar iloc , sería df[df.A > 3].index[0] .

  1. Obtener la primera fila donde A> 4 Y B> 3:

     >>> df[(df.A > 4) & (df.B > 3)].iloc[0] A 5 B 4 C 5 Name: 4, dtype: int64 
  2. Obtenga la primera fila donde A> 3 Y (B> 3 O C> 2) (devuelve la fila 2)

     >>> df[(df.A > 3) & ((df.B > 3) | (df.C > 2))].iloc[0] A 4 B 6 C 3 Name: 2, dtype: int64 

Ahora, con su último caso, podemos escribir una función que maneje el caso predeterminado de devolver el marco ordenado descendente:

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

Como era de esperar, devuelve la fila 4.

Para coincidencias existentes, utilice la query :

 df.query(' A > 3' ).head(1) Out[33]: ABC 2 4 6 3 df.query(' A > 4 and B > 3' ).head(1) Out[34]: ABC 4 5 4 5 df.query(' A > 3 and (B > 3 or C > 2)' ).head(1) Out[35]: ABC 2 4 6 3 

Puedes encargarte de los primeros 3 artículos con corte y cabezal:

  1. df[df.A>=4].head(1)
  2. df[(df.A>=4)&(df.B>=3)].head(1)
  3. df[(df.A>=4)&((df.B>=3) * (df.C>=2))].head(1)

La condición, en caso de que no regrese nada, se puede manejar con un bash o un …

 try: output = df[df.A>=6].head(1) assert len(output) == 1 except: output = df.sort_values('A',ascending=False).head(1)