Because you know the order of the columns already why not just use:
df.columns = ['Date', 'a', 'b', 'c', 'd', 'e', 'f' 'g', 'h', 'i', 'j']
Otherwise if you want to use rename you will need to assign it to a variable:
mapping = {df.columns[0]:'Date', df.columns[1]: 'A', df.columns[2]:'B', df.columns[3]: 'C',df.columns[4]:'D', df.columns[5]: 'E',df.columns[6]:'F', df.columns[7]: 'G',df.columns[8]:'H', df.columns[9]: 'J'}
df = df.rename(columns=mapping)
Answer from johnchase on Stack OverflowI have a Pandas dataframe. I have tried three different methods to rename a column, none of which are working. What am I doing wrong? Here is what I have tried:
my_df.columns = my_df.columns.str.replace(' ','_')
my_df.rename(columns={1:"Filing_Date"}, inplace=True)
my_df.rename({"Filing Date": "Filing_Date"}, axis=1, inplace=True)
my_df.dtypes
X object
Filing Date object
Trade Date object
Ticker object
Company Name object
Insider Name object
Title object
Trade Type object
Price float64
Qty float64
Owned float64
ΔOwn float64
Value float64
dtype: objectBecause you know the order of the columns already why not just use:
df.columns = ['Date', 'a', 'b', 'c', 'd', 'e', 'f' 'g', 'h', 'i', 'j']
Otherwise if you want to use rename you will need to assign it to a variable:
mapping = {df.columns[0]:'Date', df.columns[1]: 'A', df.columns[2]:'B', df.columns[3]: 'C',df.columns[4]:'D', df.columns[5]: 'E',df.columns[6]:'F', df.columns[7]: 'G',df.columns[8]:'H', df.columns[9]: 'J'}
df = df.rename(columns=mapping)
Let's assume that you have a mapping such as:
mapping = {"old_name_1" : "new_name_1", "old_name_2" : "new_name_2"}
Pandas version < 1.4.3
Given the previous documentation from pandas, the default value on axis parameter is 0 (meaning index).
Thus, changing your command to:
df = df.rename(columns = mapping, axis = 1)
, where axis equal to 1 means columns, will work as expected.
Also, you can use the inplace parameter so you won't have to re-set your DataFrame.
df.rename(columns = mapping, axis = 1, inplace = True)
Pandas version >= 1.4.3
(thanks @Gordon for the heads-up)
You can just use:
df = df.rename(columns = mapping)
or
df.rename(columns = mapping, inplace = True)
With the new update (see documentation), pandas understand that when you set a mapping to columns parameter, you mean to change the value of columns (as it is logical to happen); thus, the axis parameter is unnecessary.
I am trying to rename the columns without the spaces in between two words for further processing. but the pandas.rename function is not working, and giving the unchanged dataframe. Can anybody please point out what is going wrong here? Thanks.
import pandas as pd
country_column_rename_dict = { 'COUNTRY KEY': 'COUNTRY_KEY',
'COUNTRY NAME': 'COUNTRY_NAME'
}
data = { 'Country Key': ['NA','AF','LA','GA'],
'Country Name': ['North America', 'Africa', 'Latin America','Asia']
}
df = pd.DataFrame(data)
df.rename(columns=country_column_rename_dict, inplace=True) print(df)
# Output
Country Key Country Name
NA America
AF Africa
LA Latin America
GA Asia
following the answer from Yilun Zhang:
import pandas as pd
df = pd.DataFrame({"(1, 'Snd_Mer_Vol_Probability')": [1, 2, 3], "B": [4, 5, 6]})
print (df)
df = df.rename(columns={"(1, 'Snd_Mer_Vol_Probability')": 'Snd_Mer_Vol_Probability'})
print (df)
(1, 'Snd_Mer_Vol_Probability') B
0 1 4
1 2 5
2 3 6
Snd_Mer_Vol_Probability B
0 1 4
1 2 5
2 3 6
Could you try this instead? Assuming I've understood what you're trying to do, which is rename a column called (1, 'Snd_Mer_Vol_Probability') to Snd_Mer_Vol_Probability
Snd_Mer_Vol_Output.rename(columns={"(1, 'Snd_Mer_Vol_Probability')": 'Snd_Mer_Vol_Probability'},inplace=True)
EDIT:
You actually need:
Snd_Mer_Vol_Output.rename(columns={(1, 'Snd_Mer_Vol_Probability'): 'Snd_Mer_Vol_Probability'},inplace=True)
As your .columns output below shows that the column name is a tuple and not a string, so it doesn't need quotes (double or otherwise) around it, as you can see I've done an example myself:
df = pd.DataFrame({(1,'hello'):[1],'test':[2]})
print(df)
>> test (1, hello)
>> 2 1
df.rename(columns={(1,'hello'):'testing2'},inplace=True)
print(df)
>> test testing2
>> 2 1
df.rename fails here, because it tries to map labels per level. You can use pd.Index.map with dict.get:
df_test.columns = df_test.columns.map(lambda col: test_map.get(col, col))
Result:
df_test.columns
MultiIndex([('Group_A', 'Current_1'),
('Group_A', 'Current_2'),
('Group_B', 'Current_1'),
('Group_B', 'Metric_2')],
)
Alternative assignment possible via df.set_axis:
df_test = df_test.set_axis(
df_test.columns.map(lambda col: test_map.get(col, col)), axis=1
)
The rename method in pandas generally operates on the labels of specific levels when dealing with a MultiIndex, rather than treating the full column tuples as single keys. Because of this, passing a dictionary of tuples often fails to match the columns as you intend.
To solve this, the most reliable approach is to rebuild the index using a list comprehension or map to apply your dictionary, and then assign it back to df.columns.
When df.rename(columns=...) is called on a MultiIndex, pandas attempts to align the dictionary keys with the labels of the index levels, not the composite tuples (pairs).Since your keys are tuples and the level labels are individual strings, no match is found, and nothing changes.
import pandas as pd
cols = pd.MultiIndex.from_tuples([
('Group_A', 'Metric_1'),
('Group_A', 'Metric_2'),
('Group_B', 'Metric_1'),
('Group_B', 'Metric_2')
])
df_test = pd.DataFrame([
[10, 20, 30, 40],
[50, 60, 70, 80]
], columns=cols)
test_map = {
('Group_A', 'Metric_1'): ('Group_A', 'Current_1'),
('Group_A', 'Metric_2'): ('Group_A', 'Current_2'),
('Group_B', 'Metric_1'): ('Group_B', 'Current_1')
}
# --- Solution ---
# Create a new list of columns by looking up each tuple in your map;
# if it's not in the map, keep the original tuple.
new_columns = [test_map.get(col, col) for col in df_test.columns]
# Assign the new columns back to the DataFrame
df_test.columns = pd.MultiIndex.from_tuples(new_columns)
print("--- Check Results ---")
print(df_test.columns.tolist())