Cuestión de rendimiento pandas – Necesito ayuda para optimizar

Escribí un código de Python que hace un uso intensivo de la biblioteca de pandas. El código parece ser un poco lento, así que lo revisé a través de cProfile para ver dónde están los cuellos de botella. Uno de los cuellos de botella según los resultados de cProfile es la llamada a pandas.lib_scalar_compare:

1604 262.301 0.164 262.301 0.164 {pandas.lib.scalar_compare} 

Mi pregunta es la siguiente: ¿en qué circunstancias se llama a esto? Asumo que es cuando hago la selección de parte de un DataFrame. Aquí es como se ve mi código:

 if (var=='9999'): dataTable=resultTable.ix[(resultTable['col1'] == var1) & (resultTable['col2']==var2)].copy() else: dataTable=resultTable.ix[(resultTable['col1'] == var1) & (resultTable['col2']==var2) & (resultTable['col3']==int(val3))].copy() 

Tengo las siguientes preguntas:

  1. ¿Es ese el fragmento de código que finalmente llama al código que causa el cuello de botella?
  2. Si es así, ¿hay alguna forma de optimizar esto? La versión de pandas que estoy usando actualmente es pandas-0.8 .

Cualquier ayuda en esto sería apreciada grandemente

Mi código pasaba una tonelada de tiempo en pandas.lib.scalar_compare, y pude boost la velocidad en 10x al convertir el tipo de datos de las columnas basadas en cadenas a “categoría”.

Por ejemplo:

  $ df['ResourceName'] = df['ResourceName'].astype('category') 

Para obtener más información, consulte https://www.continuum.io/content/pandas-categoricals

Podría establecer el índice utilizando las columnas col1-col3. Aquí hay un ejemplo de juguete:

 In [1]: df = DataFrame(np.arange(20).reshape(5,4)) In [2]: df Out[2]: 0 1 2 3 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 3 12 13 14 15 4 16 17 18 19 In [3]: df2 = df.set_index(keys=[0,1,2]) In [4]: df2 Out[4]: 3 0 1 2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 

Tupla multiindex:

 In [5]: %timeit df2.ix[(4,5,6)] 10000 loops, best of 3: 99.5 us per loop 

DataFrame original:

 In [6]: %timeit df.ix[(df[0]==4) & (df[1]==5) & (df[2]==6)][3] 1000 loops, best of 3: 515 us per loop 

ACTUALIZACIÓN: Direccionamiento de índices duplicados.

 In [1]: df = DataFrame(np.arange(20).reshape(5,4)) In [2]: df = concat([df, df]) In [3]: df Out[3]: 0 1 2 3 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 3 12 13 14 15 4 16 17 18 19 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 3 12 13 14 15 4 16 17 18 19 

Esto falla:

 In [4]: df2 = df.set_index(keys=[0,1,2]) In [5]: df2.ix[(0,1,2)] KeyError: u'no item named 1' 

Esto funciona:

 In [6]: df2 = df.set_index(keys=[0,1,2]).sort() In [7]: df2.ix[(0,1,2)] Out[7]: 3 0 1 2 0 1 2 3 2 3