Pandas: ¿Cuál es la forma más eficiente de iterar sobre el DataFrame de Pandas fila por fila?

Creado en 12 jun. 2015  ·  6Comentarios  ·  Fuente: pandas-dev/pandas

He probado la función df.iterrows() pero su rendimiento es horrible. Lo cual no es sorprendente dado que iterrows() devuelve un Series con esquema completo y metadatos, no solo los valores (que son todo lo que necesito).

El segundo método que he probado es for row in df.values , que es significativamente más rápido. Sin embargo, recientemente me di cuenta de que df.values no es el almacenamiento de datos interno del DataFrame, porque df.values convierte todos los dtypes en un dtype común. Por ejemplo, una de mis columnas tiene dtype int64 pero el dtype de df.values es todo float64 . Entonces sospecho que df.values realidad crea otra copia de los datos internos.

Además, otro requisito es que la iteración de fila debe devolver una lista de valores que conserven el dtype de los datos.

Usage Question

Comentario más útil

Creo que df.itertuples() es lo que estás buscando, es mucho más rápido que iterrows:

In [10]: x = pd.DataFrame({'x': range(10000)})

In [11]: %timeit list(x.iterrows())
1 loops, best of 3: 383 ms per loop

In [12]: %timeit list(x.itertuples())
1000 loops, best of 3: 1.39 ms per loop

Todos 6 comentarios

En Python, iterar sobre las filas será (mucho) más lento que realizar operaciones vectorizadas.

Los tipos se están convirtiendo en su segundo método porque así es como funcionan las matrices numpy (que es lo que es df.values ). Los DataFrames se basan en columnas, por lo que puede tener un solo DataFrame con varios tipos de datos. Una vez que iteras por filas, todo tiene que ser upcast a un tipo más general que contenga todo. En su caso, los ints van a float64 .

Si describe su problema con un ejemplo de trabajo mínimo, es posible que podamos ayudarlo a vectorizarlo. También puede tener suerte en StackOverflow con la etiqueta pandas.

Básicamente, quiero hacer lo siguiente:

row_handler = RowHandler(sample_df)  # learn how to handle row from sample data
transformed_data = []
for row in df.values:
    transformed_data.append(row_handler.handle(row))
return transformed_data

No soy dueño de la clase RowHandler y, por lo tanto, solo puedo operar fila por fila.

Otro ejemplo similar es en el aprendizaje automático, donde puede tener un modelo que tiene API de predicción solo a nivel de fila.

Todavía es un poco demasiado vago para ser útil. Pero si RowHandler está realmente fuera de su control, entonces no tendrá suerte. FWIW todas las API de scikit-learn operan en matrices (es decir, múltiples filas).

No veo cómo puede ser más claro. Sí, RowHandler está fuera de mi control. ¿A qué te refieres con sin suerte? Mi pregunta es cuál es la forma más eficiente de iterar sobre las filas manteniendo intacto el dtype de cada elemento. ¿Estás sugiriendo df.iterrows() o algo más?

sklearn es una excepción, no la norma, que opera de forma nativa en el DataFrame PD. No muchas bibliotecas de aprendizaje automático tienen API que operen en DataFrame .

Creo que df.itertuples() es lo que estás buscando, es mucho más rápido que iterrows:

In [10]: x = pd.DataFrame({'x': range(10000)})

In [11]: %timeit list(x.iterrows())
1 loops, best of 3: 383 ms per loop

In [12]: %timeit list(x.itertuples())
1000 loops, best of 3: 1.39 ms per loop

¡Gracias @shoyer! Eso es lo que necesito.

¿Fue útil esta página
0 / 5 - 0 calificaciones