Cómo iterar sobre las filas en un DataFrame en Pandas

python pandas rows dataframe


Tengo un DataFrame de pandas:

import pandas as pd
inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}]
df = pd.DataFrame(inp)
print df

Output:

   c1   c2
0  10  100
1  11  110
2  12  120

Ahora quiero iterar sobre las filas de este cuadro.Para cada fila quiero poder acceder a sus elementos (valores en las celdas)por el nombre de las columnas.Por ejemplo:

for row in df.rows:
   print row['c1'], row['c2']

¿Es posible hacer eso en los pandas?

Encontré esta pregunta similar . Pero no me da la respuesta que necesito. Por ejemplo, se sugiere usar allí:

for date, row in df.T.iteritems():

or

for row in df.iterrows():

Pero no entiendo qué es el objeto de row y cómo puedo trabajar con él.




Answer 1 waitingkuo


DataFrame.iterrows es un generador que produce tanto índice como fila

import pandas as pd
import numpy as np

df = pd.DataFrame([{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}])

for index, row in df.iterrows():
    print(row['c1'], row['c2'])

Output: 
   10 100
   11 110
   12 120



Answer 2 cs95


¿Cómo iterar sobre las filas en un DataFrame en Pandas?

Respuesta: NO HACER * !

La iteración en los pandas es un antipatrón, y es algo que solo debe hacer cuando haya agotado todas las demás opciones. No debe usar ninguna función con " iter " en su nombre por más de unos pocos miles de filas o tendrá que acostumbrarse a esperar mucho .

¿Quieres imprimir un DataFrame? Use DataFrame.to_string() .

¿Quieres calcular algo? En ese caso, busque métodos en este orden (lista modificada desde aquí ):

  1. Vectorization
  2. Rutinas de Cython
  3. Lista de comprensiones (vainilla for bucle)
  4. DataFrame.apply() : i) Reducciones que se pueden realizar en cython, ii) Iteración en el espacio python
  5. DataFrame.itertuples() y iteritems()
  6. DataFrame.iterrows()

iterrows itertuples iterrows e itertuples (ambos reciben muchos votos en respuestas a esta pregunta) en circunstancias muy raras, como generar objetos de fila / tuplas de nombre para el procesamiento secuencial, que en realidad es lo único para lo que estas funciones son útiles.

Apelar a la autoridad
La página de documentos en la iteración tiene un gran cuadro de advertencia rojo que dice:

Iterar a través de los objetos de los pandas es generalmente lento.En muchos casos,no es necesario iterar manualmente sobre las filas [...].

* En realidad es un poco más complicado que "no". df.iterrows() es la respuesta correcta a esta pregunta, pero "vectorizar sus operaciones" es la mejor. Reconoceré que hay circunstancias en las que no se puede evitar la iteración (por ejemplo, algunas operaciones en las que el resultado depende del valor calculado para la fila anterior). Sin embargo, se necesita cierta familiaridad con la biblioteca para saber cuándo. Si no está seguro de si necesita una solución iterativa, probablemente no. PD: Para saber más sobre mi justificación para escribir esta respuesta, salte al final.


Más rápido que el bucle: vectorización , Cython

Una buena cantidad de operaciones y cálculos básicos son "vectorizados" por pandas (ya sea a través de NumPy o mediante funciones Cythonized). Esto incluye aritmética, comparaciones, (la mayoría) reducciones, remodelación (como pivotar), uniones y operaciones grupales. Consulte la documentación sobre la funcionalidad básica esencial para encontrar un método vectorizado adecuado para su problema.

Si no existe ninguno, siéntase libre de escribir el suyo usando extensiones de cython personalizadas .


Siguiente mejor cosa: Lista de comprensiones

La lista de comprensiones debería ser su próximo puerto de escala si 1) no hay una solución vectorizada disponible, 2) el rendimiento es importante, pero no lo suficientemente importante como para pasar por la molestia de cifrar su código, y 3) está tratando de realizar una transformación de elementos en tu código Hay una buena cantidad de evidencia que sugiere que las comprensiones de listas son lo suficientemente rápidas (e incluso a veces más rápidas) para muchas tareas comunes de pandas.

La fórmula es simple,

# iterating over one column - `f` is some function that processes your data
result = [f(x) for x in df['col']]
# iterating over two columns, use `zip`
result = [f(x, y) for x, y in zip(df['col1'], df['col2'])]
# iterating over multiple columns
result = [f(row[0], ..., row[n]) for row in df[['col1', ...,'coln']].values]

Si puedes encapsular tu lógica de negocios en una función,puedes usar una comprensión de lista que la llame.Puedes hacer funcionar cosas arbitrariamente complejas a través de la simplicidad y la velocidad de la pitón cruda.


Un ejemplo obvio

Vamos a demostrar la diferencia con un ejemplo sencillo de añadir dos columnas pandas A + B . Esta es una operación vectorizable, por lo que será fácil contrastar el rendimiento de los métodos discutidos anteriormente.

enter image description here

Código de referencia,para su referencia.

Debo mencionar,sin embargo,que no siempre es así de sencillo.A veces la respuesta a "cuál es el mejor método para una operación" es "depende de sus datos".Mi consejo es que pruebe diferentes enfoques en sus datos antes de decidirse por uno.


Más lecturas

* Los métodos de cadena de pandas están "vectorizados" en el sentido de que se especifican en la serie pero operan en cada elemento. Los mecanismos subyacentes siguen siendo iterativos, porque las operaciones de cadena son inherentemente difíciles de vectorizar.


Por qué escribí esta respuesta

Una tendencia común que noto de los nuevos usuarios es hacer preguntas de la forma "¿cómo puedo iterar sobre mi df para hacer X?". Mostrando código que llama a iterrows() mientras hace algo dentro de un bucle for. Aquí es por qué. Un nuevo usuario de la biblioteca que no haya sido introducido al concepto de vectorización probablemente visualizará el código que resuelve su problema al iterar sobre sus datos para hacer algo. Sin saber cómo iterar sobre un DataFrame, lo primero que hacen es buscarlo en Google y terminar aquí, en esta pregunta. Luego ven la respuesta aceptada que les dice cómo hacerlo, y cierran los ojos y ejecutan este código sin preguntarse primero si la iteración no es lo correcto.

El objetivo de esta respuesta es ayudar a los nuevos usuarios a comprender que la iteración no es necesariamente la solución a todos los problemas,y que podrían existir soluciones mejores,más rápidas y más idiomáticas,y que vale la pena invertir tiempo en explorarlas.No intento iniciar una guerra de iteración contra vectorización,pero quiero que los nuevos usuarios estén informados cuando desarrollen soluciones a sus problemas con esta biblioteca.




Answer 3 viddik13


Primero considere si realmente necesita iterar sobre filas en un DataFrame. Vea esta respuesta para alternativas.

Si aún necesita iterar sobre filas, puede usar los métodos a continuación. Tenga en cuenta algunas advertencias importantes que no se mencionan en ninguna de las otras respuestas.

itertuples() Se supone que itertuples () es más rápido que iterrows()

Pero tened en cuenta que,según los documentos (pandas 0.24.2 por el momento):

  • iterrows: dtype podría no coincidir de fila a fila

    Debido a que iterrows devuelve una serie para cada fila, no conserva los tipos de letra en las filas (los tipos de letra se conservan en las columnas para los marcos de datos). Para preservar los tipos de letra mientras itera sobre las filas, es mejor usar itertuples () que devuelve las denominadas tuplas de los valores y que generalmente es mucho más rápido que iterrows ()

  • ...las hileras:No modifique las filas

    Nunca debe modificar algo sobre lo que está iterando. No se garantiza que funcione en todos los casos. Dependiendo de los tipos de datos, el iterador devuelve una copia y no una vista, y escribir en él no tendrá ningún efecto.

    Utilice DataFrame.apply () en su lugar:

    new_df = df.apply(lambda x: x * 2)
  • itertuples:

    Los nombres de columna se renombrarán a nombres posicionales si son identificadores de Python no válidos, se repiten o comienzan con un guión bajo. Con una gran cantidad de columnas (> 255), se devuelven tuplas regulares.

Vea los documentos de pandas en iteración para más detalles.




Answer 4 Wes McKinney


Debe usar df.iterrows() . Aunque iterar fila por fila no es especialmente eficiente ya que los objetos de la Series tienen que ser creados.




Answer 5 e9t


Si bien iterrows() es una buena opción, a veces itertuples() puede ser mucho más rápido:

df = pd.DataFrame({'a': randn(1000), 'b': randn(1000),'N': randint(100, 1000, (1000)), 'x': 'x'})

%timeit [row.a * 2 for idx, row in df.iterrows()]
# => 10 loops, best of 3: 50.3 ms per loop

%timeit [row[1] * 2 for row in df.itertuples()]
# => 1000 loops, best of 3: 541 µs per loop