95
energy.loc['Republic of Korea']

I want to change the value of index from 'Republic of Korea' to 'South Korea'. But the dataframe is too large and it is not possible to change every index value. How do I change only this single value?

peterh
  • 11,875
  • 18
  • 85
  • 108
user517696
  • 2,472
  • 7
  • 24
  • 35
  • 6
    Your question is unclear, you want to change all instances of `'Republic of Korea'` or you want to know how to update lots of different index values? Please post a representative example and include your code and desired result, besides you can do `df.index.set_value(df.index, 'Republic of Korea', 'South Korea')` – EdChum Nov 04 '16 at 16:55

8 Answers8

114

@EdChum's solution looks good. Here's one using rename, which would replace all these values in the index.

energy.rename(index={'Republic of Korea':'South Korea'},inplace=True)

Here's an example

>>> example = pd.DataFrame({'key1' : ['a','a','a','b','a','b'],
           'data1' : [1,2,2,3,nan,4],
           'data2' : list('abcdef')})
>>> example.set_index('key1',inplace=True)
>>> example
      data1 data2
key1             
a       1.0     a
a       2.0     b
a       2.0     c
b       3.0     d
a       NaN     e
b       4.0     f

>>> example.rename(index={'a':'c'}) # can also use inplace=True
      data1 data2
key1             
c       1.0     a
c       2.0     b
c       2.0     c
b       3.0     d
c       NaN     e
b       4.0     f
ErnestScribbler
  • 2,667
  • 1
  • 18
  • 13
  • 5
    This should be the best answer. – Francesco Apr 28 '20 at 09:40
  • Can this be done to one level of a multiindex? – HoosierDaddy Jun 12 '21 at 07:47
  • @HoosierDaddy It can, simply by adding the argument `level='key1'` (replacing `'key1'` with the name of the level you want to change). On the downside, I've found this to be incredibly slow and expensive (in my case, 160k rows takes 36s). There may be a faster option in one of the other answers; not sure. – Neil Traft Feb 12 '22 at 19:30
82

You want to do something like this:

as_list = df.index.tolist()
idx = as_list.index('Republic of Korea')
as_list[idx] = 'South Korea'
df.index = as_list

Basically, you get the index as a list, change that one element, and the replace the existing index.

Batman
  • 8,571
  • 7
  • 41
  • 80
  • 2
    This will remove the index name if you had one to start with. Just be careful. A better way for last line is `df.index._data = np.array(as_list)` which will only change the values of the index without messing around with other attributes of the index. – Zhang18 Jul 29 '20 at 15:49
  • Even better way to do this is, instead of `as_list = df.index.tolist()` in the first line, use `as_list = df.index.values.copy()`. Then the last line should be `df.index._data = as_list.copy()`. This does not make any difference with @Zhang18 's comment AFAIK if all index is all correctly set, but if any of the index column is empty for some rows (resulting in `NaN`) and if you want to preserve other quirks of the array, you should not use `np.array(...)` as they will convert `NaN` into `'nan'`. Sidenote, `df.index.values` has `dtype=object`, so you wouldn't have problem assigning any string. – Hojin Cho Sep 11 '20 at 05:40
  • Not sure if something in Pandas has changed since this was authored, but setting `df.index._data` doesn't seem to do anything for me. It changes `._data` but does not change `.values`. As for setting `index` directly, that destroys a `MultiIndex` completely. Finally, this solution only changes the first instance of `'Republic of Korea'`, not all instances. – Neil Traft Feb 12 '22 at 19:26
20

Try This

df.rename(index={'Republic of Korea':'South Korea'},inplace=True)
  • 2
    While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – xiawi Sep 10 '19 at 13:12
  • 1
    This should be the selected answer. More info on this answer can be found at https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rename.html – LNI Sep 10 '21 at 22:51
12

If you have MultiIndex DataFrame, do this:

# input DataFrame
import pandas as pd
t = pd.DataFrame(data={'i1':[0,0,0,0,1,1,1,1,2,2,2,2],
                       'i2':[0,1,2,3,0,1,2,3,0,1,2,3],
                       'x':[1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.]})
t.set_index(['i1','i2'], inplace=True)
t.sort_index(inplace=True)

# changes index level 'i1' values 0 to -1
t.rename(index={0:-1}, level='i1', inplace=True)
S.V
  • 2,149
  • 2
  • 18
  • 41
  • @Abdul Rafay's answer works for Multi-index as well – layser Jun 07 '20 at 12:28
  • 2
    FYI the sorting has nothing to do with the answer. The answer is just the last line. (To help future readers.) – Neil Traft Feb 12 '22 at 19:34
  • @layser It should be noted that @Adbul Rafay's answer doesn't specify the `level` keyword, which can be really dangerous if you use this on a multi-index. Indeed, any matching value will be replaced in all levels. – Carmellose Mar 02 '23 at 17:28
9

Here's another good one, using replace on the column.

df.reset_index(inplace=True)
df.drop('index', axis = 1, inplace=True)
df["Country"].replace("Republic of Korea", value="South Korea", inplace=True)
df.set_index("Country", inplace=True)
Andrea C
  • 329
  • 4
  • 6
5

Here's another idea based on set_value

df = df.reset_index()
df.drop('index', axis = 1, inplace=True)
index = df.index[df["Country"] == "Republic of Korea"]
df.set_value(index, "Country", "South Korea")
df = df.set_index("Country")
df["Country"] = df.index
Andrea C
  • 329
  • 4
  • 6
  • 1
    thank you,`set_value` was what I was looking for! I was trying to set the values using something like `df.iloc[index]['Country'] = value` but was getting SettingWithCopyWarning and it wasn't working – JD D Apr 11 '19 at 14:24
2

We can use rename function to change row index or column name. Here is the example,

Suppose data frame is like given below,

       student_id     marks
index
  1        12          33
  2        23          98
  • To change index 1 to 5

we will use axis = 0 which is for row

df.rename({ 1 : 5 }, axis=0)

df refers to data frame variable. So, output will be like

       student_id     marks
index
  5        12          33
  2        23          98
  • To change column name

we will have to use axis = 1

df.rename({ "marks" : "student_marks" }, axis=1)

so, changed data frame is

       student_id     student_marks
index
  5        12              33
  2        23              98
bhargav3vedi
  • 521
  • 1
  • 6
  • 11
1

This seems to work too:

energy.index.values[energy.index.tolist().index('Republic of Korea')] = 'South Korea'

No idea though whether this is recommended or discouraged.

mpeli
  • 347
  • 3
  • 6