python - python pandas 重组索引中的内存泄漏

标签 python memory-leaks pandas

我的代码中存在内存泄漏,它试图将一个 csv 读入 pandas 中,但它对于内存来说太大了。我使用 chunksize 进行迭代,但每次迭代使用的内存量都在增加(按 block 的大小)。 在我中断进程并清除命名空间后,任务管理器中的 python 进程仍在占用 n* 大小的 block ,并完成了 n 次迭代。 有谁知道循环中的哪一步会在内存中创建一些不会被删除的东西?如果是这样,我该如何强行删除它?

import pymysql
import pandas as pd
import numpy as np
import sysconn=pymysql.connect(host='localhost', port=3306, user='root', passwd='******', db='')
curr = conn.cursor()
curr.execute('CREATE DATABASE IF NOT EXISTS addclick')
curr.execute('USE addclick')
datachunks = pd.read_csv('train.csv', chunksize=1e5)
i=0
print 'Start loading main database. This may take a while. Chunks:'
for chunk in datachunks:
    i=i+1
    print(i)
    sys.stdout.flush()
    shuffle = chunk.reindex(np.random.permutation(chunk.index))
    validationchunk = shuffle.iloc[:int(1e4)]
    validationchunk.to_sql('validation', conn, if_exists='append', flavor='mysql', index=False)
    trainchunk = shuffle.iloc[int(1e4):]
    trainchunk.to_sql('train', conn, if_exists='append', flavor='mysql', index=False)

目标是将 csv 文件拆分为训练集和验证集,并将它们放入 sql 数据库中以便于访问聚合。

最佳答案

假设您使用的是 pandas >= 0.15.0。我认为 np.random.permutation 正在改变您正在改组的索引。这是一个禁忌,因为索引是不可变的。

In [1]: df = DataFrame(np.random.randn(10000))

In [2]: def f(df):
   ...:     for dfi in np.array_split(df,100):
   ...:         shuffle = dfi.reindex(np.random.permutation(dfi.index))
   ...:         one = shuffle.iloc[:50]
   ...:         two = shuffle.iloc[50:]
   ...:         

In [3]: %memit f(df)
peak memory: 76.64 MiB, increment: 1.47 MiB

In [4]: %memit f(df)
peak memory: 77.07 MiB, increment: 0.43 MiB

In [5]: %memit f(df)
peak memory: 77.48 MiB, increment: 0.41 MiB

In [6]: %memit f(df)
peak memory: 78.09 MiB, increment: 0.61 MiB

In [7]: %memit f(df)
peak memory: 78.49 MiB, increment: 0.40 MiB

In [8]: %memit f(df)
peak memory: 78.79 MiB, increment: 0.27 MiB

所以把值取出来,你就可以操作它们了(这会返回一个 ndarray),它是可以被操作的。

In [9]: def f2(df):
   ...:     for dfi in np.array_split(df,100):
   ...:         shuffle = dfi.reindex(np.random.permutation(dfi.index.values))
   ...:         one = shuffle.iloc[:50]
   ...:         two = shuffle.iloc[50:]
   ...:         

In [10]: %memit f2(df)
peak memory: 78.79 MiB, increment: 0.00 MiB

In [11]: %memit f2(df)
peak memory: 78.79 MiB, increment: 0.00 MiB

In [12]: %memit f2(df)
peak memory: 78.79 MiB, increment: 0.00 MiB

In [13]: %memit f2(df)
peak memory: 78.79 MiB, increment: 0.00 MiB

In [14]: %memit f2(df)
peak memory: 78.80 MiB, increment: 0.00 MiB

In [15]: %memit f2(df)
peak memory: 78.80 MiB, increment: 0.00 MiB

不太确定这里是谁的错(例如保证 permutation 或索引)。

关于python - python pandas 重组索引中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27074469/

相关文章:

python - 设置基于值计数和分组依据的数据框列值

python - 仅在实际发生错误的情况下,如何仅将python错误(stderr)保存到日志文件?

python - 使用 `end="\r"` 将光标设置到开头后将光标重置为换行符

python - 使用仿射变换添加 PatchCollection

python - 设置预提交时,包需要不同的 Python : 2. 7.17 不在 '>=3.6.1' 中

iphone - UIImagePickerController 内存泄漏

python - 如何从python中的两个文件夹导入excel文件

ios - 在iOS中加载放弃内存的图片的辅助方法-如何避免这种情况?

java - 共享库分配的 JNA 空闲内存

python - 将多索引中的条件列与同一索引对齐时出现问题