4

我有一个数据框df2,它是另一个数据框的副本:

In [5]: df = DataFrame({"A":[1,2,3],"B":[4,5,6],"C":[7,8,9]})
In [6]: df
Out[6]:
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

In [7]: df2 = df.copy()

因此不是同一个对象:

In [8]: df is df2
Out[8]: False

In [9]: hex(id(df))
Out[9]: '0x89c6550L'

In [10]: hex(id(df2))
Out[10]: '0x89c6a58L'

我的问题是关于这两个数据框的列。为什么返回的列对象df.columnsdf2.columns同一个对象?

In [11]: df.columns is df2.columns
Out[11]: True

In [12]: hex(id(df.columns))
Out[12]: '0x89bfb38L'

In [13]: hex(id(df2.columns))
Out[13]: '0x89bfb38L'

但是,如果我进行更改,那么它们会成为两个独立的对象吗?

In [14]: df2.rename(columns={"B":"D"}, inplace=True)

In [15]: df.columns
Out[15]: Index([A, B, C], dtype=object)

In [16]: df2.columns
Out[16]: Index([A, D, C], dtype=object)

In [17]: df.columns is df2.columns 
Out[17]: False

In [18]: hex(id(df.columns))
Out[18]: '0x89bfb38L'

In [19]: hex(id(df2.columns))
Out[19]: '0x89bfc88L'

有人可以解释这里发生了什么吗?为什么不是从一开始就df.columnsdf2.columns两个独立的对象?

4

1 回答 1

4

df.columns 是一个索引对象。

这些是不可变对象(有点像字符串/整数是不可变的。您可以更改对对象的引用,但不能更改实际对象)。

这允许共享并因此提高性能效率(并且您在复制索引时不需要实际复制内存)。当您“更改”一个对象时,您实际上得到了一个新对象(而不是对原始对象的引用)

几乎所有的 pandas 操作都会返回一个新对象,请参见此处: http: //pandas.pydata.org/pandas-docs/stable/basics.html#copying

所以rename相当于复制然后分配给索引(列和/或索引,无论您要更改什么)。但是,这种分配行为会创建一个新的索引对象。(所以rename只是这个操作的一种方便方法)

于 2013-04-24T15:45:44.600 回答