4

I read in the documentation that the index objects are immutable and can not be changed once created. But I can change the values after creation.

Am I missing something here?

This is what I tried:

ser = pd.Series([5,0,3,8,4], index=['red','blue','yellow','white','green'])
ser

red       5
blue      0
yellow    3
white     8
green     4
dtype: int64

ser.index = ['red','blue','yellow','white','test']
ser

red       5
blue      0
yellow    3
white     8
test      4
dtype: int64
cs95
  • 379,657
  • 97
  • 704
  • 746
Isha Garg
  • 331
  • 1
  • 3
  • 12
  • 3
    It means you can't do `ser.index[0] = 'wack'` – Zero Sep 13 '17 at 09:29
  • 3
    Semantically that's slightly different, what you're doing is replacing the index with an entirely new index, but you can't change an individual index element as @JohnGalt and the answer has shown – EdChum Sep 13 '17 at 09:34

2 Answers2

8

Note that the culprit is in the __setitem__ method of the Index class:

def __setitem__(self, key, value):
    raise TypeError("Index does not support mutable operations")

This TypeError is raised when you try to set an element of the index. However, this says nothing about reassigning the index.

OTOH, if you consider df.set_index which is a method to set the index, you'll see that, at the end, this is done:

frame.index = index  # Line 3016

Meaning, you may re-assign the index at any time.


A similar example should help. Assuming, you're aware of the immutability of strings.

string = 'test'

This is possible:

string = 'test2'  # reassignment

But this is not:

string[0] = c     # item assignment... mutating the same object! 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-233-27903bb729b1> in <module>()
----> 1 s[0] = c

TypeError: 'str' object does not support item assignment

In a similar fashion mutability != reassignment. ser.index works similar to this. You may think of the index as an ordered frozenset.

cs95
  • 379,657
  • 97
  • 704
  • 746
4

You can change the object ser.index references like you've done, but you can't mutate the object once assigned:

>>> import pandas as pd
>>> ser = pd.Series([5,0,3,8,4], index=['red','blue','yellow','white','green'])
>>> ser.index[2] = 'coconut'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/indexes/base.py", line 1404, in __setitem__
    raise TypeError("Index does not support mutable operations")
TypeError: Index does not support mutable operations

>>> lst = [''] * 5
>>> ser.index = lst
>>> ser.index
Index(['', '', '', '', ''], dtype='object')
>>> lst[:] = ['Mango', 'Banana', 'Orange', 'Pear', 'Apple'] # update list
>>> lst
['Mango', 'Banana', 'Orange', 'Pear', 'Apple']
>>> ser.index
Index(['', '', '', '', ''], dtype='object')
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139