Renombrando columnas de dataframe de pandas usando un ciclo for

No estoy seguro si esta es una forma tonta de hacer las cosas, pero tengo varios marcos de datos, todos los cuales tienen columnas idénticas. Necesito cambiar el nombre de las columnas dentro de cada una para reflejar los nombres de cada dataframe (luego realizaré una combinación externa de todas estas).

Digamos que los marcos de datos se llaman df1 , df2 y df3 , y cada uno contiene el name , la date y el count las columnas.

Me gustaría cambiar el nombre de cada una de las columnas en df1 a name_df1 , date_df1 , y count_df1 .

He escrito una función para cambiar el nombre de las columnas, por lo tanto:

 df_list=[df1, df2, df3] def rename_cols(): col_name="name"+suffix col_count="count"+suffix col_date="date"+suffix for x in df_list: if x['name'].tail(1).item() == df1['name'].tail(1).item(): suffix="_"+"df1" rename_cols() continue elif x['name'].tail(1).item() == df2['name'].tail(1).item(): suffix="_"+"df2" rename_cols() continue else: suffix="_"+"df3" rename_cols() col_names=[col_name,col_date,col_count] x.columns=col_names 

Desafortunadamente, recibo el siguiente error: KeyError: 'name'

Estoy realmente luchando para averiguar por qué está pasando eso. Las columnas para df1, el primer dataframe en la lista df_list , se renombran. Todo lo demás sigue igual … ¿Estoy confundiendo la syntax básica (probablemente), o hay un malentendido fundamental que tengo de cómo funcionan las cosas?

Por lo que puedo comprobar, el primer dataframe en la lista se está iterando más de una vez, pero ¿por qué sería así?

Supongo que puedes lograr esto con algo más simple, así:

 df_list=[df1, df2, df3] for i, df in enumerate(df_list, 1): df.columns = [col_name+'_df{}'.format(i) for col_name in df.columns] 

Si tus DataFrames tienen nombres más bonitos, puedes probar:

 df_names=('Home', 'Work', 'Park') for df_name in df_names: df = globals()[df_name] df.columns = [col_name+'_{}'.format(df_name) for col_name in df.columns] 

O puede buscar el nombre de cada variable buscando en globals() (o locals() ):

 df_list = [Home, Work, Park] for df in df_list: name = [k for k, v in globals().items() if id(v) == id(df) and k[0] != '_'][0] df.columns = [col_name+'_{}'.format(name) for col_name in df.columns] 

Supongo que tienes tu almacenado en un diccionario ya que esta es la forma idiomática de almacenar una serie de objetos nombrados en Python. La forma idiomática de pandas de cambiar los nombres de sus columnas es usar una operación de cadena df.columns en df.columns :

 df_dict = {"df1":df1, "df2":df2, "df3":df3} for name, df in df_dict.items(): df.columns = df.columns + "_" + name 

Otra opción a considerar es agregar los sufijos automáticamente durante la fusión. Cuando llama a la merge , puede especificar los sufijos que se agregarán a los nombres de columna duplicados con el parámetro suffixes . Si solo desea agregar los nombres de los marcos de datos, puede llamarlo así. :

 from itertools import reduce df_merged = reduce(lambda x,y: ("df_merged", x[1].merge(y[1], left_index=True, right_index=True, suffixes = ("","_"+y[0]))), df_dict.items())[1] 

Para completar, ya que nadie ha mencionado df.rename , vea la respuesta de Andy Hayden aquí:

Renombrando columnas en pandas

df.rename puede tomar una función como un argumento, por lo que en este caso:

 df_dict = {'df1':df1,'df2':df2,'df3':df3} for name,df in df_dict.items(): df.rename(lambda x: x+'_'+name, inplace=True)