He notado un rendimiento muy bajo al usar iterrows de pandas.
¿Es esto algo que otros experimentan? ¿Es específico de iterrows y debería evitarse esta función para datos de cierto tamaño (estoy trabajando con 2-3 millones de filas)?
Esta discusión en GitHub me llevó a creer que se debe a la mezcla de dtypes en el marco de datos, sin embargo, el ejemplo simple a continuación muestra que está ahí incluso cuando se usa un dtype (float64). Esto toma 36 segundos en mi 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 qué las operaciones vectorizadas como se aplican mucho más rápido? Me imagino que también debe haber alguna iteración fila por fila.
No puedo averiguar cómo no usar iterrows en mi caso (esto lo guardaré para una pregunta futura). Por lo tanto, agradecería que me escuchara si ha podido evitar esta iteración de manera constante. Estoy haciendo cálculos basados en datos en marcos de datos separados. ¡Gracias!
--- Editar: a continuación se agregó una versión simplificada de lo que quiero ejecutar ---
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
NO está vectorizado.iterrows
es incluso peor, ya que encierra todo (con lo que 'el diferencial de rendimiento'apply
). Solo debe usarloiterrows
en muy pocas situaciones. En mi humilde opinión, nunca. Muestre lo que está haciendo realmenteiterrows
.