如何释放 pandas 数据框使用的内存?

2025-02-18 09:23:00
admin
原创
35
摘要:问题描述:我有一个非常大的 csv 文件,我在 pandas 中打开它,如下所示......import pandas df = pandas.read_csv('large_txt_file.txt') 一旦我这样做,我的内存使用量就会增加 2GB,这是意料之中的,因为这个文件包含数百万行。当我需要释放这块...

问题描述:

我有一个非常大的 csv 文件,我在 pandas 中打开它,如下所示......

import pandas
df = pandas.read_csv('large_txt_file.txt')

一旦我这样做,我的内存使用量就会增加 2GB,这是意料之中的,因为这个文件包含数百万行。当我需要释放这块内存时,问题就出现了。我跑了……

del df

但是,我的内存使用量并没有下降。这是释放 pandas 数据框使用的内存的错误方法吗?如果是,正确的方法是什么?


解决方案 1:

减少 Python 中的内存使用量很困难,因为Python 实际上不会将内存释放回操作系统。如果删除对象,则内存可供新的 Python 对象使用,但不会free()释放回系统(请参阅此问题)。

如果您坚持使用数字 numpy 数组,那么这些数组会被释放,但装箱对象则不会。

>>> import os, psutil, numpy as np # psutil may need to be installed
>>> def usage():
...     process = psutil.Process(os.getpid())
...     return process.memory_info()[0] / float(2 ** 20)
... 
>>> usage() # initial memory usage
27.5 

>>> arr = np.arange(10 ** 8) # create a large array without boxing
>>> usage()
790.46875
>>> del arr
>>> usage()
27.52734375 # numpy just free()'d the array

>>> arr = np.arange(10 ** 8, dtype='O') # create lots of objects
>>> usage()
3135.109375
>>> del arr
>>> usage()
2372.16796875  # numpy frees the array, but python keeps the heap big

减少数据帧的数量

Python 将内存保持在高水位,但我们可以减少创建的数据帧总数。修改数据帧时,请选择inplace=True,这样您就不会创建副本。

另一个常见问题是保留 ipython 中先前创建的数据框的副本:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({'foo': [1,2,3,4]})

In [3]: df + 1
Out[3]: 
   foo
0    2
1    3
2    4
3    5

In [4]: df + 2
Out[4]: 
   foo
0    3
1    4
2    5
3    6

In [5]: Out # Still has all our temporary DataFrame objects!
Out[5]: 
{3:    foo
 0    2
 1    3
 2    4
 3    5, 4:    foo
 0    3
 1    4
 2    5
 3    6}

您可以通过键入%reset Out清除历史记录来解决这个问题。或者,您可以调整 ipython 保留的历史记录量ipython --cache-size=5(默认值为 1000)。

减少数据帧大小

尽可能避免使用对象数据类型。

>>> df.dtypes
foo    float64 # 8 bytes per value
bar      int64 # 8 bytes per value
baz     object # at least 48 bytes per value, often more

具有对象 dtype 的值是装箱的,这意味着 numpy 数组只包含一个指针,而数据框中的每个值在堆上都有一个完整的 Python 对象。这包括字符串。

虽然 numpy 支持数组中的固定大小字符串,但 pandas 却不支持(这给用户带来了困惑)。这会带来很大的不同:

>>> import numpy as np
>>> arr = np.array(['foo', 'bar', 'baz'])
>>> arr.dtype
dtype('S3')
>>> arr.nbytes
9

>>> import sys; import pandas as pd
>>> s = pd.Series(['foo', 'bar', 'baz'])
dtype('O')
>>> sum(sys.getsizeof(x) for x in s)
120

您可能希望避免使用字符串列,或者找到一种将字符串数据表示为数字的方法。

如果您有一个包含许多重复值(NaN 非常常见)的数据框,那么您可以使用稀疏数据结构来减少内存使用量:

>>> df1.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 39681584 entries, 0 to 39681583
Data columns (total 1 columns):
foo    float64
dtypes: float64(1)
memory usage: 605.5 MB

>>> df1.shape
(39681584, 1)

>>> df1.foo.isnull().sum() * 100. / len(df1)
20.628483479893344 # so 20% of values are NaN

>>> df1.to_sparse().info()
<class 'pandas.sparse.frame.SparseDataFrame'>
Int64Index: 39681584 entries, 0 to 39681583
Data columns (total 1 columns):
foo    float64
dtypes: float64(1)
memory usage: 543.0 MB

查看内存使用情况

您可以查看内存使用情况(文档):

>>> df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 39681584 entries, 0 to 39681583
Data columns (total 14 columns):
...
dtypes: datetime64[ns](1), float64(8), int64(1), object(4)
memory usage: 4.4+ GB

从 pandas 0.17.1 开始,您还可以df.info(memory_usage='deep')查看包括对象在内的内存使用情况。

解决方案 2:

正如评论中所述,有一些事情可以尝试:gc.collect例如,(@EdChum) 可能会清除一些东西。至少从我的经验来看,这些事情有时有效,但通常无效。

然而,有一件事总是有效的,因为它是在操作系统而不是语言层面完成的。

假设您有一个函数,它创建一个中间巨大的 DataFrame,并返回一个较小的结果(也可能是一个 DataFrame):

def huge_intermediate_calc(something):
    ...
    huge_df = pd.DataFrame(...)
    ...
    return some_aggregate

然后如果你做类似的事情

import multiprocessing

result = multiprocessing.Pool(1).map(huge_intermediate_calc, [something_])[0]

然后该函数在另一个进程中执行。当该进程完成时,操作系统将重新占用它使用的所有资源。Python、pandas 和垃圾收集器实际上无法阻止这种情况。

解决方案 3:

这帮我解决了释放内存的问题!!!

import gc
import pandas as pd

del [[df_1,df_2]]
gc.collect()
df_1=pd.DataFrame()
df_2=pd.DataFrame()

数据框将明确设置为空

在上述声明中

首先,数据框的自引用被删除,这意味着在数据框的所有引用都被垃圾收集器(gc.collect())收集后,数据框不再可供 Python 使用,然后将所有引用明确设置为空数据框。

有关垃圾收集器的工作原理的更多信息,请参阅https://stackify.com/python-garbage-collection/

解决方案 4:

del df`df如果在删除时有任何对 的引用,则不会被删除。因此您需要使用 删除对它的所有引用del df`以释放内存。

因此,应删除与 df 绑定的所有实例以触发垃圾收集。

使用objgragh检查哪个正在抓住物体。

解决方案 5:

glibc 似乎存在一个问题,影响了 Pandas 中的内存分配:https://github.com/pandas-dev/pandas/issues/2659

关于这个问题的详细介绍的猴子补丁已经为我解决了这个问题:

# monkeypatches.py

# Solving memory leak problem in pandas
# https://github.com/pandas-dev/pandas/issues/2659#issuecomment-12021083
import pandas as pd
from ctypes import cdll, CDLL
try:
    cdll.LoadLibrary("libc.so.6")
    libc = CDLL("libc.so.6")
    libc.malloc_trim(0)
except (OSError, AttributeError):
    libc = None

__old_del = getattr(pd.DataFrame, '__del__', None)

def __new_del(self):
    if __old_del:
        __old_del(self)
    libc.malloc_trim(0)

if libc:
    print('Applying monkeypatch for pd.DataFrame.__del__', file=sys.stderr)
    pd.DataFrame.__del__ = __new_del
else:
    print('Skipping monkeypatch for pd.DataFrame.__del__: libc or malloc_trim() not found', file=sys.stderr)

解决方案 6:

以下是我为解决这个问题所采取的措施。

我有一个小应用程序,它将大型数据集读入 pandas 数据框并将其作为 api 提供。然后,用户可以通过将查询参数传递给 api 来查询数据框。当用户读入多个数据集时,应用程序显然会面临内存使用限制。

不要将数据集读入单个数据框变量,而是将它们读入数据框字典。

df_file_contents[file_name] = pd.read_csv(..)

已向前端提供 api 来清除字典。这将调用字典的 clear() 方法。可以自定义当 sys.getsizeof(df_file_contents) 达到特定大小时调用该方法,或者用于删除某些键。

df_file_contents.clear()

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1325  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它涵盖了从产品概念产生到产品退市的整个生命周期,通过整合跨部门团队、优化流程等方式,显著提升产品开发的效率和质量,进而为项目的成功奠定坚实基础。深入探究IPD流程的五个阶段与项目成功之间...
IPD流程分为几个阶段   4  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,其中的创新管理与实践更是蕴含着丰富的经验和深刻的智慧,对众多企业具有重要的借鉴意义。IPD流程的核心架构IPD流程旨在打破部门墙,实现跨部门的高效协作,将产品开发视为一个整体的流程。它涵盖了从市场需求分析...
华为IPD是什么   3  
  IPD(Integrated Product Development)研发管理体系作为一种先进的产品开发模式,在众多企业的发展历程中发挥了至关重要的作用。它不仅仅是一套流程,更是一种理念,一种能够全方位提升企业竞争力,推动企业持续发展的有效工具。深入探究IPD研发管理体系如何助力企业持续发展,对于众多渴望在市场中立足并...
IPD管理流程   3  
  IPD(Integrated Product Development)流程管理旨在通过整合产品开发流程、团队和资源,实现产品的快速、高质量交付。在这一过程中,有效降低成本是企业提升竞争力的关键。通过优化IPD流程管理中的各个环节,可以在不牺牲产品质量和性能的前提下,实现成本的显著降低,为企业创造更大的价值。优化产品规划...
IPD流程分为几个阶段   4  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用