python - pandas DataFrame 中的内存处理

标签 python pandas

我需要对 pandas DataFrame() 执行一些操作以评估某些度量,但让我的 DataFrame 保持原样。所以我认为我应该从在内存中复制它开始:

import pandas as pd
df1 = pd.DataFrame({'a':[1,2,3]})
df2 = pd.DataFrame(df1)

打印时

print(id(df1), id(df2))

我确实得到了两个不同的系统地址。所以在我看来,这是 DataFrame() 的两个不同实例。

但是,如果我这样做:

df2['b'] = [4,5,6]
print(df1)

df1 出现时带有“b”列,尽管我只在 df2 中添加了它。

为什么会这样? 我怎样才能真正复制我的 DataFrame 以便对一个的操作不会修改另一个? 我在 Python 3.5 和 pandas 0.24.2

最佳答案

您需要使用 pd.DataFrame.copy

df2 = df1.copy()

一个赋值,即使你赋值给一个新变量,也会引用内存中的相同数据/索引,这意味着对 df1 或 df2 的操作将改变内存中的相同数据。然而,使用复制,df2 获得了自己的数据副本,可以独立操作。


解释:

为什么在 DataFrame 上调用 pd.DataFrame 时会得到两个不同的内存地址?

简单地说,pandas.DataFramenumpy.ndarry 的包装器。当您使用 df1 数据帧作为输入调用 pd.DataFrame 时,会创建一个新的 pd.DataFrame 包装器(因此不同的内存地址),但数据完全相同。您可以使用以下代码验证:

In [2]: import pandas as pd
   ...: df1 = pd.DataFrame({'a':[1,2,3]})
   ...: df2 = pd.DataFrame(df1)
   ...: 

In [3]: print(id(df1), id(df2))
(4665009296, 4665009360)

In [4]: df1._data
Out[4]: 
BlockManager
Items: Index([u'a'], dtype='object')
Axis 1: RangeIndex(start=0, stop=3, step=1)
IntBlock: slice(0, 1, 1), 1 x 3, dtype: int64

In [5]: id(df1._data)
Out[5]: 4522343248

In [6]: id(df2._data)
Out[6]: 4522343248

如您所见,df1._datadf2._data 的内存地址完全相同。

这个看DataFrame源码也清楚in github ,其中,在构造函数的开头,新数据帧引用相同的数据:

if isinstance(data, DataFrame):
    data = data._data

关于python - pandas DataFrame 中的内存处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55812035/

相关文章:

python - 语法推理库?

python - 如何避免解码为 str : need a bytes-like object error in pandas?

python - 计算每行的 "best of 4"平均值

python - Pandas 读取 csv 正在移动列

Python Pandas read_csv 保持列顺序

python - 在linux中使用Python创建SFTP用户

python - 是否有用于 python 的已建立的 memoize 磁盘装饰器?

带有刻度标签的 Python PyQt4 slider

python - Pandas DataFrame 索引的操作

python - 如何从包含列表的嵌套Python字典中的键中删除符号?