250

I was looking for an elegant way to change a specified column name in a DataFrame.

play data ...

import pandas as pd
d = {
         'one': [1, 2, 3, 4, 5],
         'two': [9, 8, 7, 6, 5],
         'three': ['a', 'b', 'c', 'd', 'e']
    }
df = pd.DataFrame(d)

The most elegant solution I have found so far ...

names = df.columns.tolist()
names[names.index('two')] = 'new_name'
df.columns = names

I was hoping for a simple one-liner ... this attempt failed ...

df.columns[df.columns.tolist().index('one')] = 'another_name'

Any hints gratefully received.

Mark Graph
  • 4,969
  • 6
  • 25
  • 37

10 Answers10

447

A one liner does exist:

In [27]: df=df.rename(columns = {'two':'new_name'})

In [28]: df
Out[28]: 
  one three  new_name
0    1     a         9
1    2     b         8
2    3     c         7
3    4     d         6
4    5     e         5

Following is the docstring for the rename method.

Definition: df.rename(self, index=None, columns=None, copy=True, inplace=False)
Docstring:
Alter index and / or columns using input function or
functions. Function / dict values must be unique (1-to-1). Labels not
contained in a dict / Series will be left as-is.

Parameters
----------
index : dict-like or function, optional
    Transformation to apply to index values
columns : dict-like or function, optional
    Transformation to apply to column values
copy : boolean, default True
    Also copy underlying data
inplace : boolean, default False
    Whether to return a new DataFrame. If True then value of copy is
    ignored.

See also
--------
Series.rename

Returns
-------
renamed : DataFrame (new object)
Nipun Batra
  • 11,007
  • 11
  • 52
  • 77
130

Since inplace argument is available, you don't need to copy and assign the original data frame back to itself, but do as follows:

df.rename(columns={'two':'new_name'}, inplace=True)
Jeong-Yoon Lee
  • 1,401
  • 1
  • 10
  • 7
51

What about?

df.columns[2] = "new_name"
Jacob H
  • 4,317
  • 2
  • 32
  • 39
  • 15
    actually that doesn't work if later you use the column name on other operations like in df['new_name'] – Master Yogurt Jul 04 '16 at 16:46
  • 4
    this answer was useful for me to change a specific column to a new name. 1st column is index 0, 2nd column is index 1, and so on. nice solution.. and i am sure this will help more people.. as the other solutions require you to know and copy the original column names beforehand.... while this is quick and dirty method.. which has its own uses. – ihightower Sep 30 '17 at 17:27
  • 2
    @MasterYogurt your comment is not correct. It is possible to perform `df['new_name']` (and other pandas things) after changing variables as outlined above. Your comment may have been valid when it was originally posted. – Jacob H Sep 29 '18 at 21:12
  • 1
    That being said, using the `rename` methods is a better solution. – Jacob H Sep 29 '18 at 21:13
  • @JacobH I still run into this issue with Pandas v1.0.3 – Philipp Oct 20 '20 at 14:08
17

If you know which column # it is (first / second / nth) then this solution posted on a similar question works regardless of whether it is named or unnamed, and in one line: https://stackoverflow.com/a/26336314/4355695

df.rename(columns = {list(df)[1]:'new_name'}, inplace=True)
# 1 is for second column (0,1,2..)
Nikhil VJ
  • 5,630
  • 7
  • 34
  • 55
  • This works only if there is not "nan" in the column names, otherwise it will change all of them. – Hackerman Oct 11 '22 at 04:10
  • 1
    The only solution for me - I had a list of lists converted to a DF with columns 0,1,..250, and I only needed to "name" the first three columns. This worked perfectly. – KayCee Aug 31 '23 at 08:32
11

Pandas 0.21 now has an axis parameter

The rename method has gained an axis parameter to match most of the rest of the pandas API.

So, in addition to this:

df.rename(columns = {'two':'new_name'})

You can do:

df.rename({'two':'new_name'}, axis=1)

or

df.rename({'two':'new_name'}, axis='columns')
Ted Petrou
  • 59,042
  • 19
  • 131
  • 136
  • df.rename({'two':'new_name'}, axis='columns') Throws TypeError: Cannot specify both 'axis' and any of 'index' or 'columns'. – HereHere Dec 30 '17 at 23:37
  • @HereHere Make sure you are on pandas version 0.21. Do `pd.__version__` to check your version – Ted Petrou Dec 30 '17 at 23:49
4

For renaming the columns here is the simple one which will work for both Default(0,1,2,etc;) and existing columns but not much useful for a larger data sets(having many columns).

For a larger data set we can slice the columns that we need and apply the below code:

df.columns = ['new_name','new_name1','old_name']
Aylen
  • 3,524
  • 26
  • 36
4

pandas version 0.23.4

df.rename(index=str,columns={'old_name':'new_name'},inplace=True)

For the record:

omitting index=str will give error replace has an unexpected argument 'columns'

Malakai
  • 3,011
  • 9
  • 35
  • 49
Kallol Medhi
  • 457
  • 1
  • 5
  • 17
  • 1
    This extends nicely for more than one column: if you have a list of the `old_names` and the `new-names` (one for one), then you can do: `df.rename(columns=dict(zip(old_names, new_names)), inplace=True)` – Colin Sep 03 '21 at 08:58
3

Following short code can help:

df3 = df3.rename(columns={c: c.replace(' ', '') for c in df3.columns})

Remove spaces from columns.

  • I kept getting `AttributeError: 'int' object has no attribute 'replace'` could you expand on that. – Nirmal May 14 '19 at 15:41
2

Another option would be to simply copy & drop the column:

df = pd.DataFrame(d)
df['new_name'] = df['two']
df = df.drop('two', axis=1)
df.head()

After that you get the result:

    one three   new_name
0   1   a       9
1   2   b       8
2   3   c       7
3   4   d       6
4   5   e       5
anka
  • 3,817
  • 1
  • 30
  • 36
  • 2
    This method will not help in case the order of the columns indexes is important. The new column will be created at the end. – Loochie Jan 09 '19 at 11:08
0

size = 10
df.rename(columns={df.columns[i]: someList[i] for i in range(size)}, inplace = True)
erptocoding
  • 305
  • 3
  • 5