中国十大门户网站,建筑公司企业文化,网站建设规划书企业网站,安卓市场app下载最近我用python处理excel#xff0c;使用的是pandas库#xff0c;我发现pandas库非常占用内存#xff0c;一直想研究下如何优化pandas的内存占用#xff0c;但一直没腾出空来#xff0c;最近终于有时间研究一把了#xff0c;我先把优化方法写上#xff0c;如果你想了解更… 最近我用python处理excel使用的是pandas库我发现pandas库非常占用内存一直想研究下如何优化pandas的内存占用但一直没腾出空来最近终于有时间研究一把了我先把优化方法写上如果你想了解更多的内容可以看一下XX这篇文章我优化的思路来源https://www.sohu.com/a/484114754_121124370这篇文章。 以下直接提供了优化方法如果你想知道为什么这么做可以参考我的另一篇文章链接: python pandas 优化内存占用(二)
1.优化结果
1.1 优化前 我优化的是一个20万行88列的excel文件源文件有76.59M,因为业务敏感性的原因源文件我不能贴出来。 先看一下优化之前excel占用了多少内存
# class pandas.core.frame.DataFrame
# RangeIndex: 200000 entries, 0 to 199999
# Data columns (total 88 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 column0 200000 non-null int64
# 1 column1 200000 non-null object
# 2 column2 200000 non-null int64
......
# 85 column85 199963 non-null float64
# 86 column86 199963 non-null object
# 87 column87 199963 non-null float64
# dtypes: float64(14), int64(3), object(71)
# memory usage: 965.9 MB上面的输出我精简了一下从上边的输出可以看出我的excel文件有200000行88列其中有14个float64类型的列3个int64类型的列71个ojbect类型的列总共占用内存965.9M。 上面的输出是使用如下的代码得到的。
gl.info(memory_usagedeep)1.2 优化后
# class pandas.core.frame.DataFrame
# RangeIndex: 200000 entries, 0 to 199999
# Data columns (total 88 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 column0 200000 non-null uint64
# 1 column1 200000 non-null object
# 2 column2 200000 non-null uint64
......
# 84 是否小区 199963 non-null category
# 85 column85 199963 non-null category
# 86 column86 199963 non-null category
# 87 column87 199963 non-null category
# dtypes: category(81), object(5), uint64(2)
# memory usage: 143.8 MB同样我把优化后的输出也精简了一下从上边的输出可以看出我这个200000行88列的excel文件优化后占用内存143.8M优化效果还是非常明显的。 细心的小伙伴可能注意到一个问题优化后我的execl文件的列类型变化了优化前有14个float64类型的列3个int64类型的列71个ojbect类型的列优化后变成了81个category类型的列5个object类型列2个uint64类型的列。没错正如你看到的这就是优化的秘密为什么这样可以优化内存使用可以参看我的另一篇文章下面我讲一下我是如何做到的。
2. 优化方法 正如小伙伴在上文中看到的要想优化excel的内存占用大小一个重要的思路是改变excel的列类型如何获取优化后的列类型呢代码如下
import pandas as pd
# 把excel中的数据类型转化成优化后的数据类型
def convert_to_right_type():# 读取文件gl pd.read_excel(xx.xlsx)# 初始化一个DataFrameconverted_obj pd.DataFrame()# 计算哪些列类型可以转换成category类型for col in gl.columns:num_unique_values len(gl[col].unique())num_total_values len(gl[col])if num_unique_values / num_total_values 0.5:converted_obj.loc[:, col] gl[col].astype(category)else:converted_obj.loc[:, col] gl[col]# 计算哪些int类型列可以downcast成子类型gl_int converted_obj.select_dtypes(include[int])converted_int gl_int.apply(pd.to_numeric, downcastunsigned)# 将转换后的int类型列合并回converted_objfor col in converted_int.columns:converted_obj[col] converted_int[col]# 计算哪些float类型列可以downcast成子类型gl_float converted_obj.select_dtypes(include[float])converted_float gl_float.apply(pd.to_numeric, downcastfloat)# 将转换后的 float 类型列合并回converted_objfor col in converted_float.columns:converted_obj[col] converted_float[col]# 获取数据类型索引(索引是列名值是数据类型)dtypes converted_obj.dtypes# 获取列名dtypes_col dtypes.index# 获取数据类型的名称dtypes_type [i.name for i in dtypes.values]# 列名和类型字典column_types dict(zip(dtypes_col, dtypes_type))# preview {key: value for key, value in list(column_types.items())[:20]}# 获取字典preview {key: value for key, value in list(column_types.items())}# 格式化输出, 使每个嵌套层级的缩进量为4个空格pp pprint.PrettyPrinter(indent4)# 打印字典pp.pprint(preview)这段儿代码的输出类似如下
column_types {column1: category,column2: uint64,column3: object,column4: uint64,column5: category}column_type 是个字典它的key是excel文件的列名称value是excel文件列对应的优化后的类型。 在读取excel的时候指定excel的dtype即可按照指定的列类型读取excel类似这样
gl pd.read_excel(XX.xlsx, dtypecolumn_types)3. 测试方法 我是用如下的代码测试excel占用内存的大小的
# 测试内存占用
def mem_usage(pandas_obj):if isinstance(pandas_obj, pd.DataFrame):usage_b pandas_obj.memory_usage(deepTrue).sum()else: # we assume if not a df its a seriesusage_b pandas_obj.memory_usage(deepTrue)usage_mb usage_b / 1024 ** 2 # convert bytes to megabytesreturn {:03.2f} MB.format(usage_mb)