python - 如何释放 Pandas 数据框使用的内存?

标签 python pandas memory

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

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

执行此操作后,我的内存使用量会增加 2GB,这是意料之中的,因为该文件包含数百万行。当我需要释放此内存时,我的问题就来了。我跑了....

del df

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

最佳答案

在 Python 中减少内存使用很困难,因为 Python does not actually release memory back to the operating system .如果您删除对象,则内存可用于新的 Python 对象,但不能free()返回系统 (see this question)。

如果你坚持使用数字 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 --cache-size=5 调整 ipython 保留多少历史记录(默认为 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

具有 object dtype 的值被装箱,这意味着 numpy 数组只包含一个指针,并且对于数据帧中的每个值,您在堆上都有一个完整的 Python 对象。这包括字符串。

虽然 numpy 支持数组中固定大小的字符串,但 pandas 不支持 (it's caused user confusion)。这可能会产生重大影响:

>>> 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 很常见),那么您可以使用 sparse data structure减少内存使用:

>>> 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

查看内存使用情况

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

>>> 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') 来查看包括对象在内的内存使用情况。

关于python - 如何释放 Pandas 数据框使用的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39100971/

相关文章:

python - 在 Pandas 中按年/月/日分组

python - 查找与不同年份匹配的所有月份、日期和时间,并取它们的平均值

asp.net - session 变量保存在哪里?

python - 使用 matplotlib 将灰度图像转换为 RGB 热图图像

python - 如何修复 Google Cloud Vision 的段错误?

python - 删除特定行 Pandas 数据框上方的所有行

python - 如何将具有字符串和大量(数字)的列分成两列

python - 如何仅按小时聚合 Pandas 日期时间轴系列

C、FLT_MAX值大于32位?

python - 在 Python 中强制垃圾收集以释放内存