tablas - seleccionar filas y columnas en python
¿Cómo iterar sobre filas en un DataFrame en Pandas? (14)
¿Por qué complicar las cosas?
Sencillo.
import pandas as pd
import numpy as np
# Here is an example dataframe
df_existing = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list(''ABCD''))
for idx,row in df_existing.iterrows():
print row[''A''],row[''B''],row[''C''],row[''D'']
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
Salida:
c1 c2
0 10 100
1 11 110
2 12 120
Ahora quiero iterar sobre las filas de este marco. Por cada fila quiero poder acceder a sus elementos (valores en 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 utilizar:
for date, row in df.T.iteritems():
o
for row in df.iterrows():
Pero no entiendo qué es el objeto de row
y cómo puedo trabajar con él.
Agregando a las respuestas anteriores, a veces un patrón útil es:
# Borrowing @KutalmisB df example
df = pd.DataFrame({''col1'': [1, 2], ''col2'': [0.1, 0.2]}, index=[''a'', ''b''])
# The to_dict call results in a list of dicts
# where each row_dict is a dictionary with k:v pairs of columns:value for that row
for row_dict in df.to_dict(orient=''records''):
print(row_dict)
Lo que resulta en:
{''col1'':1.0, ''col2'':0.1}
{''col1'':2.0, ''col2'':0.2}
En mi humilde opinión, la decisión más simple
for ind in df.index:
print df[''c1''][ind], df[''c2''][ind]
Estaba buscando Cómo iterar en filas Y columnas y terminé aquí, así que:
for i, row in df.iterrows():
for j, column in row.iteritems():
print(column)
Para hacer un bucle de todas las filas en un dataframe
puede usar:
for x in range(len(date_example.index)):
print date_example[''Date''].iloc[x]
Para hacer un bucle de todas las filas en un dataframe
y usar los valores de cada fila de manera conveniente , las namedtuples
se pueden convertir a ndarray
s. Por ejemplo:
df = pd.DataFrame({''col1'': [1, 2], ''col2'': [0.1, 0.2]}, index=[''a'', ''b''])
Iterando sobre las filas:
for row in df.itertuples(index=False, name=''Pandas''):
print np.asarray(row)
resultados en:
[ 1. 0.1]
[ 2. 0.2]
Tenga en cuenta que si index=True
, el índice se agrega como el primer elemento de la tupla , lo que puede ser indeseable para algunas aplicaciones.
Para iterar a través de la fila de DataFrame en pandas se puede usar:
for index, row in df.iterrows(): print row["c1"], row["c2"]
pandas.pydata.org/pandas-docs/stable/generated/…
for row in df.itertuples(index=True, name=''Pandas''): print getattr(row, "c1"), getattr(row, "c2")
Se supone que itertuples()
es más rápido que iterrows()
Pero ten en cuenta, según los documentos (pandas 0.21.1 en este momento):
iterrows:
dtype
podría no coincidir de una fila a otraDebido a que iterrows devuelve una Serie para cada fila, no conserva los tipos a lo largo de las filas (los tipos se conservan en las columnas para DataFrames).
iterrows: no modificar filas
Nunca debes modificar algo sobre lo que estás iterando. Esto no está garantizado para trabajar en todos los casos. Dependiendo de los tipos de datos, el iterador devuelve una copia y no una vista, y la escritura no tendrá efecto.
Utilice DataFrame.apply() lugar:
new_df = df.apply(lambda x: x * 2)
itertuples
Los nombres de las columnas serán renombrados a nombres posicionales si son identificadores de Python no válidos, se repiten o comienzan con un guión bajo. Con un gran número de columnas (> 255), se devuelven las tuplas normales.
Puede utilizar la función df.iloc de la siguiente manera:
for i in range(0, len(df)):
print df.iloc[i][''c1''], df.iloc[i][''c2'']
Puedes escribir tu propio iterador que implementa namedtuple
from collections import namedtuple
def myiter(d, cols=None):
if cols is None:
v = d.values.tolist()
cols = d.columns.values.tolist()
else:
j = [d.columns.get_loc(c) for c in cols]
v = d.values[:, j].tolist()
n = namedtuple(''MyTuple'', cols)
for line in iter(v):
yield n(*line)
Esto es directamente comparable a pd.DataFrame.itertuples
. Estoy apuntando a realizar la misma tarea con más eficiencia.
Para el marco de datos dado con mi función:
list(myiter(df))
[MyTuple(c1=10, c2=100), MyTuple(c1=11, c2=110), MyTuple(c1=12, c2=120)]
O con pd.DataFrame.itertuples
:
list(df.itertuples(index=False))
[Pandas(c1=10, c2=100), Pandas(c1=11, c2=110), Pandas(c1=12, c2=120)]
Una prueba completa
Probamos hacer que todas las columnas estén disponibles y subcontratar las columnas.
def iterfullA(d):
return list(myiter(d))
def iterfullB(d):
return list(d.itertuples(index=False))
def itersubA(d):
return list(myiter(d, [''col3'', ''col4'', ''col5'', ''col6'', ''col7'']))
def itersubB(d):
return list(d[[''col3'', ''col4'', ''col5'', ''col6'', ''col7'']].itertuples(index=False))
res = pd.DataFrame(
index=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
columns=''iterfullA iterfullB itersubA itersubB''.split(),
dtype=float
)
for i in res.index:
d = pd.DataFrame(np.random.randint(10, size=(i, 10))).add_prefix(''col'')
for j in res.columns:
stmt = ''{}(d)''.format(j)
setp = ''from __main__ import d, {}''.format(j)
res.at[i, j] = timeit(stmt, setp, number=100)
res.groupby(res.columns.str[4:-1], axis=1).plot(loglog=True);
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
También puede usar df.apply()
para iterar sobre filas y acceder a varias columnas para una función.
def valuation_formula(x, y):
return x * y * 0.5
df[''price''] = df.apply(lambda row: valuation_formula(row[''x''], row[''y'']), axis=1)
También puedes hacer indexación numpy
para incluso mayores numpy
de velocidad. No es realmente iterador, pero funciona mucho mejor que la iteración para ciertas aplicaciones.
subset = row[''c1''][0:5]
all = row[''c1''][:]
También es posible que desee convertirlo en una matriz. Estos índices / selecciones se supone que actúan como matrices Numpy ya, pero me encontré con problemas y era necesario emitir
np.asarray(all)
imgs[:] = cv2.resize(imgs[:], (224,224) ) #resize every image in an hdf5 file
Utilice itertuples () . Es más rápido que iterrows () :
for row in df.itertuples():
print "c1 :",row.c1,"c2 :",row.c2
iterrows es un generador que produce tanto el índice como la fila.
for index, row in df.iterrows():
print row[''c1''], row[''c2'']
Output:
10 100
11 110
12 120