Tengo un dataframe de pandas que se parece a esto (es bastante grande)
date exer exp ifor mat 1092 2014-03-17 American M 528.205 2014-04-19 1093 2014-03-17 American M 528.205 2014-04-19 1094 2014-03-17 American M 528.205 2014-04-19 1095 2014-03-17 American M 528.205 2014-04-19 1096 2014-03-17 American M 528.205 2014-05-17
ahora me gustaría iterar fila por fila y al pasar por cada fila, el valor de ifor
en cada fila puede cambiar dependiendo de algunas condiciones y necesito buscar otro dataframe.
Ahora, ¿cómo actualizo esto como itero? Probé algunas cosas que ninguna de ellas funcionó.
for i, row in df.iterrows(): if : row['ifor'] = x else: row['ifor'] = y df.ix[i]['ifor'] = x
Ninguno de estos enfoques parece funcionar. No veo los valores actualizados en el dataframe.
Puede asignar valores en el bucle usando df.set_value:
for i, row in df.iterrows(): ifor_val = something if : ifor_val = something_else df.set_value(i,'ifor',ifor_val)
Si no necesita los valores de fila, simplemente puede iterar sobre los índices de df, pero conservé el bucle for original en caso de que necesite el valor de fila para algo que no se muestra aquí.
actualizar
df.set_value () ha quedado en desuso desde la versión 0.21.0, puede usar df.at () en su lugar:
for i, row in df.iterrows(): ifor_val = something if : ifor_val = something_else df.at[i,'ifor'] = ifor_val
El objeto Pandas DataFrame debe considerarse como una serie de series. En otras palabras, debes pensar en términos de columnas. La razón por la que esto es importante es porque cuando usas pd.DataFrame.iterrows
estás iterando a través de filas como Series. Pero estas no son las Series que el dataframe está almacenando, por lo que son nuevas Series que se crean para usted mientras itera. Eso implica que cuando intenta asignarles esas ediciones, esas ediciones no se reflejarán en el dataframe original.
Ok, ahora que está fuera del camino: ¿Qué hacemos?
Las sugerencias anteriores a esta publicación incluyen:
pd.DataFrame.set_value
está en desuso a partir de la versión 0.21 de Pandas pd.DataFrame.ix
está en desuso pd.DataFrame.loc
está bien, pero puede funcionar en indexadores de matriz y puede hacerlo mejor Mi recomendación
Utilice pd.DataFrame.at
for i in df.index: if : df.at[i, 'ifor'] = x else: df.at[i, 'ifor'] = y
Incluso puedes cambiar esto a:
for i in df.index: df.at[i, 'ifor'] = x if else y
y ¿qué pasa si necesito usar el valor de la fila anterior para la condición if?
for i in range(1, len(df) + 1): j = df.columns.get_loc('ifor') if : df.iat[i - 1, j] = x else: df.iat[i - 1, j] = y
Un método que puede usar es itertuples()
, itera sobre filas de DataFrame como se nombra timbres, con valor de índice como primer elemento de la tupla. Y es mucho más rápido en comparación con iterrows()
. Para itertuples()
, cada row
contiene su Index
en el dataframe, y puede usar loc
para establecer el valor.
for row in df.itertuples(): if : df.at[row.Index, 'ifor'] = x else: df.at[row.Index, 'ifor'] = x df.loc[row.Index, 'ifor'] = x
Gracias @SantiStSupery, usar .at
es mucho más rápido .
Debe asignar un valor mediante df.ix[i, 'exp']=X
o df.loc[i, 'exp']=X
lugar de df.ix[i]['ifor'] = x
.
De lo contrario, está trabajando en una vista y debería obtener un calentamiento:
-c:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
Pero ciertamente, el bucle probablemente debería ser reemplazado por algún algoritmo vectorizado para hacer un uso completo de DataFrame
como sugirió @Phillip Cloud.
Bueno, si vas a iterar de todos modos, ¿por qué no usar el método más simple de todos, df['Column'].values[i]
df['Column'] = '' for i in range(len(df)): df['Column'].values[i] = something/update/new_value
O si desea comparar los valores nuevos con el anterior o algo así, ¿por qué no lo almacena en una lista y luego lo agrega al final?
mylist, df['Column'] = [], '' for : mylist.append(something/update/new_value) df['Column'] = mylist
for i, row in df.iterrows(): if : df.at[i, 'ifor'] = x else: df.at[i, 'ifor'] = y
Incrementa el número MAX de una columna. Por ejemplo :
df1 = [sort_ID, Column1,Column2] print(df1)
Mi salida:
Sort_ID Column1 Column2 12 ae 45 bf 65 cg 78 dh
MAX = df1['Sort_ID'].max() #This returns my Max Number
Ahora, necesito crear una columna en df2 y completar los valores de columna que incrementan el MAX.
Sort_ID Column1 Column2 79 a1 e1 80 b1 f1 81 c1 g1 82 d1 h1
Nota: inicialmente, df2 solo contendrá la Columna1 y la Columna2. Necesitamos que la columna Sortid sea creada e incremental del MAX desde df1.