Tenho notado um desempenho muito fraco ao usar iterrows de pandas.
Isso é algo experimentado por outras pessoas? É específico para iterrows e essa função deve ser evitada para dados de um determinado tamanho (estou trabalhando com 2-3 milhões de linhas)?
Essa discussão no GitHub me levou a acreditar que isso é causado pela mistura de dtypes no dataframe, no entanto, o exemplo simples abaixo mostra que está lá mesmo ao usar um dtype (float64). Isso leva 36 segundos na minha máquina:
import pandas as pd
import numpy as np
import time
s1 = np.random.randn(2000000)
s2 = np.random.randn(2000000)
dfa = pd.DataFrame({'s1': s1, 's2': s2})
start = time.time()
i=0
for rowindex, row in dfa.iterrows():
i+=1
end = time.time()
print end - start
Por que as operações vetorizadas como aplicar são muito mais rápidas? Eu imagino que deve haver alguma iteração linha por linha acontecendo lá também.
Não consigo descobrir como não usar iterrows no meu caso (vou guardar para uma pergunta futura). Portanto, gostaria de saber se você tem conseguido evitar essa iteração de forma consistente. Estou fazendo cálculos com base em dados em dataframes separados. Obrigado!
--- Editar: versão simplificada do que eu quero executar foi adicionada abaixo ---
import pandas as pd
import numpy as np
#%% Create the original tables
t1 = {'letter':['a','b'],
'number1':[50,-10]}
t2 = {'letter':['a','a','b','b'],
'number2':[0.2,0.5,0.1,0.4]}
table1 = pd.DataFrame(t1)
table2 = pd.DataFrame(t2)
#%% Create the body of the new table
table3 = pd.DataFrame(np.nan, columns=['letter','number2'], index=[0])
#%% Iterate through filtering relevant data, optimizing, returning info
for row_index, row in table1.iterrows():
t2info = table2[table2.letter == row['letter']].reset_index()
table3.ix[row_index,] = optimize(t2info,row['number1'])
#%% Define optimization
def optimize(t2info, t1info):
calculation = []
for index, r in t2info.iterrows():
calculation.append(r['number2']*t1info)
maxrow = calculation.index(max(calculation))
return t2info.ix[maxrow]
apply
NÃO é vetorizado.iterrows
é ainda pior, pois encaixa tudo (que 'o desempenho difere comapply
). Você só deve usariterrows
em muito poucas situações. IMHO nunca. Mostre com o que você está realmente fazendoiterrows
.