python内存优化_python数据处理中内存优化的一些tricks

1、读入数据时,pandas默认int类型为int64,未采用最省类型方式读取,可通过以下方式优化内存

1)数值型能用更低内存类型保存就转换为更低内存类型

2) 将object类型转换为category类型

category 类型在底层使用整型数值来表示该列的值,而不使用原值.Pandas用一个字典来构建这些整型数据到原数据的映射关系.当一列只包含有有限种值时,这种设计不错。当我们把一列转换为category类型时,pandas会用一种最省空间的int子类型来表示这一列,对于缺失值,category子类型会将缺失数据设为-1.如果某一列全都是唯一值,category类型将会占用更多内存,这是因为这样做不仅要存储全部的原始字符串数据,还要存储整型类别标识.

代码如下:

def reduce_mem_usage(df, verbose=True):

numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']

cateics = ['object']

start_mem = df.memory_usage().sum() / 1024**2

for col in df.columns:

col_type = df[col].dtypes

num_unique_values = len(df[col].unique())

num_total_values = len(df[col])

if col_type in numerics:

c_min = df[col].min()

c_max = df[col].max()

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)

if (col_type in cateics) and (num_unique_values*1.0/num_total_values < 0.5):

df[col] = df[col].astype('category')

end_mem = df.memory_usage().sum() / 1024**2

if verbose:

print('Mem. usage decreased to {:5.2f} Mb ({:.1f}% reduction)'.format(

end_mem, 100 * (start_mem - end_mem) / start_mem))

return df

2、分批读入处理

pandas.read_csv('',iterator = True, chunksize = 10000)

分批处理数据:

如取众数,即分批求类别次数后,再在外面整合求所有类别次数,得到次数最大类别

如取平均值,记录分批长度及平均值,再在外面整合最终平均值

如取中位数,即分批求类别次数后,再在外面整合求所有类别次数,排序后得到中间次数类别

3、及时回收不需要的变量

import gc

del a

gc.collect()

4、pandas.read_csv 使用指定列,指定类型读取,指定时间读取,低内存消耗等等

1) dtype:指定每列数据的数据类型,如{'a':np.float64,'b':np.int32}

2) usecols:返回一个数据子集,这个参数可以加快加载速度并降低内存消耗

3) low_memory:分块加载到内存,在低内存消耗解析,可能出现类型混淆。为避免类型混淆,需设置False,或者使用dtype参数指定类型。

4) memory_map:

如果使用文件在内存内,直接map文件使用.使用这种方式可以避免文件再次IO操作

5) parse_dates:

boolean.True -> 解析索引

list of ints or names. e.g. If [1,2,3] -> 解析1,2,3列的值作为独立的日期列;

list of lists. e.g.If [[1,3]] -> 合并1,3列作为一个日期列使用

dict, e.g. {'foo':[1,3]} -> 将1,3列合并,并给合并后的列起名为"foo"

5、谨防驻留字符串

python会记录如字符串等不可改变的值(其每个值的大小依赖于实现方法)

t = "abcdefghijklmnopqrstuvwxyz"

p = "abcdefghijklmnopqrstuvwxyz"

id(t)

id(p)

如果两个字符串拥有相同的ID或引用——他们是全等的

如果你的程序创建了许多小的字符串,你的内存就会出现膨胀

6、生成字符串时使用Format来代替"+"

st = "{0}_{1}_{2}_{3}".format(a,b,c,d) #对内存更好,不创建临时变量

st2 = a + '_' + b + '_' + c + '_' + d #在每个"+"时创建一个临时str, 这些都是驻留在内存中的

当我们将某些字符串构造从"+" 变为使用format时, 内存会明显被节省。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值