Mejora la velocidad de filtrado del marco de datos de Pandas

9

Tengo un conjunto de datos con 19 columnas y aproximadamente 250k filas. He trabajado con conjuntos de datos más grandes, pero esta vez, Pandas decidió jugar con mis nervios.

Traté de dividir el conjunto de datos original en 3 subtramas de datos basados ​​en algunas reglas simples. Sin embargo, lleva mucho tiempo ejecutar el código. Unos 15-20 segundos solo para el filtrado.

¿Alguna forma alternativa de mejorar el rendimiento del código?

import pandas as pd

#read dataset
df = pd.read_csv('myData.csv')

#create a dataframe with col1 10 and col2 <= 15
df1 = df[(df.col1 == 10) & (df.col2 <= 15)]
df = df[~df.isin(df1)].dropna()

#create a dataframe with col3 7 and col4 >= 4
df2 = df[(df.col3 == 7) & (df.col4 >= 4)]
df = df[~df.isin(df2)].dropna()

Al final, tengo los df1, df2, dfmarcos de datos con los datos filtrados.

Tasos
fuente

Respuestas:

15

El concepto a entender es que el condicional es en realidad un vector. Por lo tanto, simplemente puede definir las condiciones y luego combinarlas lógicamente, como:

condition1 = (df.col1 == 10) & (df.col2 <= 15)
condition2 = (df.col3 == 7) & (df.col4 >= 4)

# at this point, condition1 and condition2 are vectors of bools

df1 = df[condition1]
df2 = df[condition2 & ~condition1]
df = df[~ (condition1 | condition2)]

Esto será considerablemente más rápido ya que solo evalúa el condicional una vez. Luego los usa para realizar búsquedas indexadas para crear los nuevos marcos de datos más pequeños.

Stephen Rauch
fuente
En caso de presencia de None o NaN, solo tenga en cuenta que la lógica booleana puede no funcionar en ellos.
kawingkelvin
5

¿Ha cronometrado qué línea de su código consume más tiempo? Sospecho que la línea df = df[~df.isin(df1)].dropna()tomaría mucho tiempo. ¿Sería más rápido si se utiliza simplemente la negación de la condición que se aplica para obtener df1, cuando se desea filtrar filas de distancia de df1de df?

Es decir, uso df = df[(df.col1 != 10) | (df.col2 > 15)].

Albert
fuente
+1 por recomendar el cronometraje de cada línea
kbrose