python - 为什么 memory_usage() 和 memory_usage(deep=True) 之间有如此大的差异?

标签 python pandas

有人可以详细说明调用DataFrame的memory_usage方法时参数deep=True的作用吗?我从文档中了解到,它“钻取”到具有对象数据类型的列,以查看这些值实际占用内存的量。但什么是“正确”的值呢? DataFrame 实际上占用了我多少内存?

我在 DataFrame df 中加载了磁盘上大约 2GB 的文件。如果没有深度,我感觉我有正确的值,因为我得到了接近文件大小的东西。使用 deep=true...我得到了这个值的 7 倍,而我的电脑甚至没有足够的 RAM 来容纳这个!

>>> memus = df.memory_usage()
>>> memusdeep = df.memory_usage(deep=True)
>>> print(memus.sum() / 10**9, 'GB')
1.874067408 GB
>>> print(memusdeep.sum() / 10**9, 'GB') # that's very much!
13.897614776 GB

如果我在任务管理器中查看 python 程序使用的内存,我会看到一个值从 250MB 到大约 1.87GB 不等(与 deep=False 相同)。这是否意味着我的列在不使用时会从内存中“释放”,并且如果我使用所有列,总内存使用量可能会达到 deep=True 宣布的 13.9 GB?

最佳答案

我的理解是,首先是documentation .

它谈论的是字节,你需要了解字节是什么。我链接到你Wikipedia page 。现在,我们将以文档为例并理解它。您需要了解一点点类型在较低级语言(例如 C 或 C++)中的工作方式(例如,intfloat ,...)。

dtypes = ['int64', 'float64', 'complex128', 'object', 'bool']
data = dict([(t, np.ones(shape=5000).astype(t))
             for t in dtypes])
df = pd.DataFrame(data)
df.head()
#   int64  float64  complex128 object  bool
#0      1      1.0      (1+0j)      1  True
#1      1      1.0      (1+0j)      1  True
#2      1      1.0      (1+0j)      1  True
#3      1      1.0      (1+0j)      1  True
#4      1      1.0      (1+0j)      1  True

df.memory_usage(index=False)
#int64         40000
#float64       40000
#complex128    80000
#object        40000
#bool           5000

关于boolean ,这相当容易。它有 2 种可能的状态,因此将保持 0(假)或 1(真)。它将存储在单个字节(8 位)中。

现在,对于其他列:int64float64意味着您有一个包含 64 位的整数,即 8 个字节。比之前的大 8 倍 boolean值(value) !如果我们看上面的df.memory_usage(),它就很简单地得到了验证。 ,如果我们乘以 bool 的 memuse列(5000)乘以 8(字节),它确实回答 40000 .

同样的逻辑适用于 complex128 。 128 位变为 16 字节,乘以 5000 列得出 80000。memuse 返回的数字。

<小时/>

事情变得棘手的地方。

df['object'].memory_usage(index=False)
#40000
df['object'].memory_usage(index=False, deep=True)
#160000L

object在 pandas 中,从技术上讲是一系列的事情。 Pandas 基本上是 numpy 的抽象用于容纳任何类型的物体,这就是它如此广泛使用的原因。 Numpy 只能存储数值数据,但 pandas 几乎可以存储任何类型,因为它包括 iterationstrings 结合.

加载 DataFrame 时,您只需要第一个引用数据即可使用它。当您不激活deep=True时选项,它不会搜索整个 DataFrame 的用法,但它实际使用的是什么:意味着对数据的第一个指针/引用(因为,非常简单地说,第一个引用导致它指向的数据 AND,使用我们对这个引用的了解,我们知道下一个引用将在哪里),这是一个 64 位数据,所以 8 字节数据,所以 40000没有 deep=True 的 5000 行字节选项。

关于python - 为什么 memory_usage() 和 memory_usage(deep=True) 之间有如此大的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54326284/

相关文章:

python - Django - 数据库数据未显示在应用程序中?

python - 用另一列的值替换字符串的一部分

python - 如何从 pandas 数据框中选择特定列项目作为列表?

python - 如何使用 Python 在 3D 图形表面上绘制图像文件? - 不绘制为平面

python - 我有一个包含 0 和 1 值的数组。如果我将其与 -1 相乘,则会产生空数组。为什么?

python - DataFrame 相关性产生 NaN,尽管它的值都是整数

python - 合并两个具有相同列的相似数据框

string - Pandas :将多列转换为字符串

python 模拟库 - 在单元测试时修补类

python - 按模式读取文件