我有一个数据框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.columns
和df2.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.columns
和df2.columns
从一开始就没有两个独立的对象?
答案 0 :(得分:4)
df.columns是一个Index对象。
这些是不可变对象(类似于字符串/整数是不可变的。你可以将引用更改为一个,但不能更改实际对象。)
这允许共享并因此提高性能效率(并且在复制索引时不需要实际复制内存)。当你'改变'一个,你真的得到一个新的对象(而不是对原始对象的引用)
几乎所有的pandas操作都会返回一个新对象,请参见此处:http://pandas.pydata.org/pandas-docs/stable/basics.html#copying
所以rename
等同于复制然后分配给索引(列和/或索引,无论你要改变什么)。但是,这种赋值行为会创建一个新的索引对象。
(因此rename
只是此操作的便捷方法)