所以我一直在尝试使用 pandas read_csv
函数读取内存中的 3.2GB 文件,但我不断遇到某种内存泄漏,我的内存使用量会飙升 90%+
.
作为替代方案
我尝试定义
dtype
以避免将数据作为字符串保留在内存中,但看到了类似的行为。尝试了 numpy read csv,认为我会得到一些不同的结果,但绝对是错误的。
尝试逐行阅读遇到了同样的问题,但速度非常慢。
我最近转向了 python 3,因此认为那里可能存在一些错误,但在 python2 + pandas 上看到了类似的结果。
相关文件是来自 Kaggle 竞赛的 train.csv 文件 grupo bimbo
系统信息:
内存:16GB,处理器:i7 8核
如果您还想了解其他信息,请告诉我。
谢谢:)
编辑 1:内存峰值!没有泄漏(对不起,我的错。)
编辑 2:csv 文件示例
Semana,Agencia_ID,Canal_ID,Ruta_SAK,Cliente_ID,Producto_ID,Venta_uni_hoy,Venta_hoy,Dev_uni_proxima,Dev_proxima,Demanda_uni_equil
3,1110,7,3301,15766,1212,3,25.14,0,0.0,3
3,1110,7,3301,15766,1216,4,33.52,0,0.0,4
3,1110,7,3301,15766,1238,4,39.32,0,0.0,4
3,1110,7,3301,15766,1240,4,33.52,0,0.0,4
3,1110,7,3301,15766,1242,3,22.92,0,0.0,3
编辑3:文件中的行号74180465
然后是一个简单的pd.read_csv('filename', low_memory=False)
我已经尝试过
from numpy import genfromtxt
my_data = genfromtxt('data/train.csv', delimiter=',')
更新 下面的代码刚刚工作,但我仍然想弄清楚这个问题的根源,一定有什么问题。
import pandas as pd
import gc
data = pd.DataFrame()
data_iterator = pd.read_csv('data/train.csv', chunksize=100000)
for sub_data in data_iterator:
data.append(sub_data)
gc.collect()
编辑:一段有效的代码。 感谢所有帮助人员,我通过添加 python 数据类型而不是 numpy 数据类型搞乱了我的数据类型。一旦我修复了下面的代码就可以正常工作。
dtypes = {'Semana': pd.np.int8,
'Agencia_ID':pd.np.int8,
'Canal_ID':pd.np.int8,
'Ruta_SAK':pd.np.int8,
'Cliente_ID':pd.np.int8,
'Producto_ID':pd.np.int8,
'Venta_uni_hoy':pd.np.int8,
'Venta_hoy':pd.np.float16,
'Dev_uni_proxima':pd.np.int8,
'Dev_proxima':pd.np.float16,
'Demanda_uni_equil':pd.np.int8}
data = pd.read_csv('data/train.csv', dtype=dtypes)
这将内存消耗降低到略低于 4Gb
最佳答案
作为文本存储在内存中的文件不像压缩的二进制格式那么紧凑,但它在数据方面相对紧凑。如果是一个简单的ascii文件,除了任何文件头信息之外,每个字符只有1个字节。 Python 字符串也有类似的关系,其中内部 Python 内容会产生一些开销,但每个额外的字符仅添加 1 个字节(来自使用 __sizeof__
进行的测试)。一旦开始转换为数字类型和集合(列表、数组、数据框等),开销就会增加。例如,列表必须存储每个位置的类型和值,而字符串仅存储值。
>>> s = '3,1110,7,3301,15766,1212,3,25.14,0,0.0,3\r\n'
>>> l = [3,1110,7,3301,15766,1212,3,25.14,0,0.0,3]
>>> s.__sizeof__()
75
>>> l.__sizeof__()
128
一点测试(假设__sizeof__
是准确的):
import numpy as np
import pandas as pd
s = '1,2,3,4,5,6,7,8,9,10'
print ('string: '+str(s.__sizeof__())+'\n')
l = [1,2,3,4,5,6,7,8,9,10]
print ('list: '+str(l.__sizeof__())+'\n')
a = np.array([1,2,3,4,5,6,7,8,9,10])
print ('array: '+str(a.__sizeof__())+'\n')
b = np.array([1,2,3,4,5,6,7,8,9,10], dtype=np.dtype('u1'))
print ('byte array: '+str(b.__sizeof__())+'\n')
df = pd.DataFrame([1,2,3,4,5,6,7,8,9,10])
print ('dataframe: '+str(df.__sizeof__())+'\n')
返回:
string: 53
list: 120
array: 136
byte array: 106
dataframe: 152
关于python - 读取 3.2 GB 文件时 Pandas/Python 内存峰值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38487334/