函数
在处理大型数据集的时候,经常碰见python把内存吃满的情况,影响性能,此时就可以对数据集在内存中的存储方式进行优化。所用函数如下:
pandas.DataFrame.memory_usage(index=True, deep=False)
返回该数据框所用的字节数(bytes)
index参数控制索引占用字节是否出现在结果中。
deep参数返回object对象在系统层面(不是很懂)的存储消耗。
pandas.to_numeric(arg, errors=‘raise’, downcast=None)
arg参数传入数据。
error参数控制无效解析返回方式。
downcast参数选择压缩的数据类型,包含‘integer’, ‘signed’, ‘unsigned’, ‘float’四种类型。
实例
import pandas as pd
import numpy as np
df = pd.read_csv('/newstart/data/train.csv')
df.info()
载入泰坦尼克数据集,返回以下结果:
dtype返回数据类型,发现有三种类型分别是int64,object,float64,那么可以将其压缩为int8,category,和float32。看看目前的内存消耗,总共占约83.7KB。以下为各列所耗字节数:
df.memory_usage()
Index 128
PassengerId 7128
Survived 7128
Pclass 7128
Name 7128
Sex 7128
Age 7128
SibSp 7128
Parch 7128
Ticket 7128
Fare 7128
Cabin 7128
Embarked 7128
dtype: int64
定义内存压缩函数:
def downcast(df):
start_memory = df.memory_usage().sum() #返回一开始的使用内存
for column in df.columns: #循环所有列变量
dtype_name = df[column].dtype.name #获取变量类型
if dtype_name == 'object':
pass #由于这里有姓名和船票,不方便直接转为分类变量
#df[column] = df[column].astype('category') #像Embarked就可以转为分类变量压缩
elif dtype_name == 'bool': #如果有布尔值可以转换为0,1压缩
df[column] = df[column].astype('int8')
elif dtype_name.startswith('int') or (df[column].round() == df[column]).all():
df[column] = pd.to_numeric(df[column], downcast='integer') #压缩整数列,这里年龄是浮点数也可以换成整数存储
else:
df[column] = pd.to_numeric(df[column], downcast='float') #压缩浮点数
end_memory = df.memory_usage().sum() #返回压缩后的使用内存
print('{:.1f}% compressed'.format(100 * (start_memory - end_memory) / start_memory))
#返回压缩比
return df
downcast(df)
返回结果:
43.7% compressed。和原来相比压缩近一半的存储空间。
对比上面可以发现int型数据从7128字节压缩到了891字节,也就是从int64转换为了int8,巨大提升。