在用python处理数据处理的时候有时候会碰到较大的数据集,可能会出现Memory Error 的问题,经过我的尝试,总结了如下几个方案。
首先扩展一下python查看内存的方法:
import psutil
import os
info = psutil.virtual_memory()
print('内存使用:',psutil.Process(os.getpid()).memory_info().rss)
print('总内存:',info.total)
print('内存占比:',info.percent)
print('CPU个数:',psutil.cpu_count())
输出:
内存使用: 1083351040
总内存: 17074249728
内存占比: 24.1
CPU个数: 4
python的psutil包可以查看内存的使用情况,直接点任务管理器也可以查看电脑的内存使用占比,还可以kill掉一些不用的进程来释放内存。但是如果想要释放掉python占用的内存,比如一些使用过后续又不再需要的数据,可以导入gc包直接删除掉数据并回收内存。
import gc
del user_log
gc.collect()
输出:
19037
修改数据类型的长度,可以对数据进行内存压缩,从而减少内存的占用。
import time
# 对数据进行内存压缩
def reduce_mem_usage(df):
starttime = time.time()
numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
start_mem = df.memory_usage().sum() / 1024**2
for col in df.columns:
col_type = df[col].dtypes
if col_type in numerics:
c_min = df[col].min()
c_max = df[col].max()
if pd.isnull(c_min) or pd.isnull(c_max):
continue
if str(col_type)[:3] == 'int':
if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
df[col] = df[col].astype(np.int8)
elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
df[col] = df[col].astype(np.int16)
elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
df[col] = df[col].astype(np.int32)
elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
df[col] = df[col].astype(np.int64)
else:
if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
df[col] = df[col].astype(np.float16)
elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
df[col] = df[col].astype(np.float32)
else:
df[col] = df[col].astype(np.float64)
end_mem = df.memory_usage().sum() / 1024**2
print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
print('Decreased by {:.1f}%'.format(100*(start_mem-end_mem)/start_mem))
return df
读文件的时候可以逐行读取或者分块读取,避免一次性把数据都读入到内存里,导致程序崩掉。
data = []
with open(path, 'r',encoding='gbk',errors='ignore') as f:
for line in f:
data.append(line.split(','))
user_log_file = r'./file.csv'
read_chunks = pd.read_csv(user_log_file,iterator=True,chunksize=500000)
user_log = pd.DataFrame()
for chunk in read_chunks:
chunk = reduce_mem_usage(chunk)
user_log = user_log.append(chunk)
扩大磁盘虚拟内存:
1、打开 控制面板;
2、找到 系统 这一项;
3、找到 高级系统设置 这一项;
4、点击 性能 模块的 设置 按钮;
5、选择 高级,在 虚拟内存 模块点击更改;
6、选择一个你文件运行的磁盘,点击自定义大小
记得 不要 选中“自动管理所有驱动器的分页文件大小”,手动输入初始大小和最大值,当然,最好不要太大,更改之后能在查看盘的使用情况,不要丢掉太多空间。
7、都设置好之后,记得点击 “设置”, 然后再确定,否则无效,最后 重启电脑 就可以了。(一开始我没有重启电脑,还是跑不动,一度怀疑自己的硬件问题。)
如果还有其他方法可以解决内存问题,欢迎留言交流~