对 pandas DataFrame memory_usage 和副本感到困惑
Posted
技术标签:
【中文标题】对 pandas DataFrame memory_usage 和副本感到困惑【英文标题】:Confused by pandas DataFrame memory_usage and copies 【发布时间】:2020-05-03 12:55:18 【问题描述】:我正在研究如何通过删除列来释放内存。
import numpy as np
import pandas as pd
big_df = pd.DataFrame(np.random.randn(100000,20))
big_df.memory_usage().sum()
> 16000128
现在有various ways 将列的子集复制 放入新的数据框。我们来看看其中几个的内存使用情况。
small_df = big_df[[0, 1]]
small_df.memory_usage().sum()
> 1600128
small_df_filtered = big_df.filter([0, 1], axis='columns')
small_df_filtered.memory_usage().sum()
> 1600128
small_df_copied = big_df[[0, 1]].copy()
small_df_copied.memory_usage().sum()
> 1600128
small_df_dropped = big_df.drop([0, 1], axis='columns')
small_df_dropped.memory_usage().sum()
> 14400128
small_df_dropped = big_df.drop([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], axis='columns')
small_df_dropped.memory_usage().sum()
> 1600128
添加deep=True
不会改变结果。
复制后添加del big_df
不会改变结果。
因此,这些较小的副本中没有一个比原始数据帧占用更少的内存,甚至更奇怪的删除 18 列保持内存不变,但删除 2 个增加内存。
发生了什么事?这些真的是副本吗?如果是这样,为什么它们不比原来的小?
【问题讨论】:
第一个切片少了一个数字。在复制时,大小保持与切片数据帧相同。 太棒了,冒着让我看起来像个白痴的风险,你可以把它写成答案@Vishnudev 【参考方案1】:原始数据帧
big_df = pd.DataFrame(np.random.randn(100000,20))
big_df.memory_usage().sum()
内存使用:16000128
即1.6x10^7
在切片上,
small_df = big_df[[0, 1]]
small_df.memory_usage().sum()
内存使用:1600128
即1.6x10^6
切片中少了一位数字。在复制时,大小保持与切片数据帧相同。
在删除第 0 列和第 1 列时,所有其他列都会保留,因此内存会激增
small_df_dropped = big_df.drop([0, 1], axis='columns')
small_df_dropped.memory_usage().sum()
内存使用:14400128
即1.4x10^7
【讨论】:
【参考方案2】:来自另一个问题:
Memory is not released when taking a small slice of a DataFrame
“正如@Alex 所说,切片数据帧只会让您看到原始帧,但不会删除它;您需要为此使用 .copy()。但是,即使我使用了 .copy(),内存使用量不断增长,尽管速度较慢。
我怀疑这与 Python、numpy 和 pandas 使用内存的方式有关。数据框不是内存中的单个对象;它包含指向其他对象的指针(特别是在这种特殊情况下,指向字符串,即“标志”列)。当数据帧被释放,并且这些对象被释放时,回收的空闲内存空间可以被碎片化。稍后,当创建一个巨大的新数据帧时,它可能无法使用碎片空间,并且可能需要分配新空间。细节取决于很多小东西,比如 Python、numpy 和 pandas 版本,以及每个案例的细节。”
【讨论】:
以上是关于对 pandas DataFrame memory_usage 和副本感到困惑的主要内容,如果未能解决你的问题,请参考以下文章
Pandas:如何从给定(行,列)对列表的 DataFrame 中检索值?
pandas对dataframe进行排序:单数据列排序多数据列排序NA值排序位置排序算法