Melhore a velocidade de filtragem do quadro de dados do Pandas

9

Eu tenho um conjunto de dados com 19 colunas e cerca de 250k linhas. Eu trabalhei com conjuntos de dados maiores, mas desta vez o Pandas decidiu brincar com meus nervos.

Tentei dividir o conjunto de dados original em 3 subframes com base em algumas regras simples. No entanto, leva muito tempo para executar o código. Cerca de 15 a 20 segundos apenas para a filtragem.

Alguma maneira alternativa de melhorar o desempenho do 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()

No final, eu tenho os df1, df2, dfquadros de dados com os dados filtrados.

Tasos
fonte

Respostas:

15

O conceito a entender é que o condicional é realmente um vetor. Portanto, você pode simplesmente definir as condições e combiná-las logicamente, 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)]

Isso será consideravelmente mais rápido, uma vez que apenas avalia o condicional uma vez. Em seguida, ele os utiliza para executar uma pesquisa indexada para criar os novos quadros de dados menores.

Stephen Rauch
fonte
No caso de presença de None ou NaN, tenha cuidado, pois a lógica booleana pode não funcionar neles.
Kawingkelvin
5

Você cronometrou qual linha do seu código consome mais tempo? Eu suspeito que a linha df = df[~df.isin(df1)].dropna()levaria muito tempo. Seria mais rápido se você simplesmente usar a negação da condição que você aplicado para obter df1, quando você deseja filtrar afastado linhas em df1partir df?

Ou seja, use df = df[(df.col1 != 10) | (df.col2 > 15)].

Albert
fonte
1 para recomendar temporização cada linha
kbrose