所以我一直试图用pandas read_csv
函数读取内存中的一个3.2GB的文件,但是我不断地遇到某种内存泄漏,我的内存使用量会激增90%+
。在
作为替代品
我尝试定义dtype
以避免将数据作为字符串保存在内存中,但是看到了类似的行为。
尝试了numpy read csv,以为我会得到一些不同的结果,但这是绝对错误的。
试着逐行阅读也遇到了同样的问题,但速度很慢。
我最近搬到了Python3,所以我认为那里可能有一些bug,但是在python2+pandas上看到了类似的结果。
有问题的文件是火车.csv来自kaggle竞赛的文件grupo bimbo
系统信息:
RAM: 16GB, Processor: i7 8cores
如果你还想知道其他情况,请告诉我。在
谢谢:)
编辑一:这是一个记忆高峰!一点也不漏(对不起我的错)
编辑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)
我试过了
^{pr2}$更新 下面的代码刚刚起作用,但是我还是想弄清楚这个问题,一定是出了什么问题。在
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以下
根据您的第二张图表,您的计算机可能会在短时间内分配额外的4.368GB内存,这大约相当于3.2GB数据集的大小(假设1GB的开销,这可能是一个扩展)。在
我试图找到一个可能发生这种情况的地方,但没有取得成功。不过,如果你有动力的话,也许你能找到它。我走的路是:
This line显示:
这里,} 。在
_engine
引用^{反过来,调用^{} 。在
调用数据^{} 。在
它似乎以字符串的形式从一些相对标准的东西中读入(参见here),比如TextIOWrapper。在
所以东西被当作标准文本读入并转换,这就解释了慢斜坡的原因。在
扣球呢?我想这可以用these lines来解释:
^{pr2}$ret
成为数据帧的所有组件。在self._create_index()
将ret
分成以下几个部分:到目前为止,一切都可以通过引用完成,对
DataFrame()
的调用延续了这一趋势(请参见here)。在所以,如果我的理论是正确的,}沿着我确定的路径在某处复制数据。在
DataFrame()
要么在某处复制数据,要么{以文本形式存储在内存中的文件不像压缩的二进制格式那样紧凑,但是它在数据方面相对紧凑。如果它是一个简单的ascii文件,除了任何文件头信息,每个字符只有1个字节。Python字符串有一个类似的关系,在这种关系中,内部Python内容会有一些开销,但是每个额外的字符只添加1个字节(通过
__sizeof__
进行测试)。一旦开始转换为数值类型和集合(列表、数组、数据帧等),开销就会增加。例如,列表必须为每个位置存储一个类型和一个值,而字符串只存储一个值。在一点测试(假设
^{pr2}$__sizeof__
是准确的):退货:
相关问题 更多 >
编程相关推荐