Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regarding the immutability of pandas dataframe indexes

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
like image 622
Isha Garg Avatar asked Dec 13 '22 20:12

Isha Garg


2 Answers

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.

like image 188
cs95 Avatar answered Dec 16 '22 10:12

cs95


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')
like image 21
Moses Koledoye Avatar answered Dec 16 '22 11:12

Moses Koledoye