【问题标题】:Regarding the immutability of pandas dataframe indexes关于 pandas 数据框索引的不变性
【发布时间】:2017-09-13 20:36:00
【问题描述】:

我在文档中读到索引对象是不可变的,一旦创建就不能更改。但是我可以在创建后更改值。

我错过了什么吗?

这是我尝试过的:

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

【问题讨论】:

  • 表示你不能做ser.index[0] = 'wack'
  • 语义上略有不同,您正在做的是用一个全新的索引替换索引,但您不能像@JohnGalt那样更改单个索引元素,答案已经显示

标签: python pandas dataframe immutability


【解决方案1】:

请注意,罪魁祸首在Index类的__setitem__方法中:

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

当您尝试设置索引的元素时,会引发此 TypeError。但是,这并没有说明重新分配索引。

OTOH,如果您考虑df.set_index 这是一种设置索引的方法,您会看到,最后,这已经完成了:

frame.index = index  # Line 3016

意思是,您可以随时重新分配索引。


一个类似的例子应该会有所帮助。假设您知道字符串的不变性。

string = 'test'

这个是可能的:

string = 'test2'  # reassignment

但是这个不是:

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

以类似的方式可变性!=重新分配。 ser.index 与此类似。你可能会认为index 是一个有序的frozenset。

【讨论】:

    【解决方案2】:

    您可以像您所做的那样更改对象ser.index引用,但是一旦分配,您就不能改变对象:

    >>> 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')
    

    【讨论】:

      猜你喜欢
      • 2013-07-07
      • 2020-10-22
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多