暴减内存!pandas 自动优化骚操作

简介: 本篇是pandas骚操作系列的第 24 篇:自动优化数据类型,暴省内存!系列内容,请看👉「pandas骚操作」话题,订阅后文章更新可第一时间推送至订阅号。内容也同步我的GitHub,欢迎star!

平日工作里经常会听到周边小伙伴说:我X,内存又爆了!

对于这样的话我听了不下百遍。正因为如此,在资源有限的情况下,我们都是变着法的减少内存占用,一些常用的方法如:

  1. gc.collectdel回收
  2. 使用csv的替代品,如featherParquet
  3. 优化代码,尽量使用Numpy矩阵代替for循环和apply
  4. ...


本次再分享一个骚操作,就是通过改变数据类型来压缩内存空间。之前也和大家介绍过category类型,也可以减少一些内存占用。和这个方法一样,我们可以延伸到所有数据类型。

正常情况下,pandas 会给数据列自动设置默认的数据类型,其中最令人讨厌并且最消耗内存的数据类型就是object(O),这也恰好限制了 pandas 的一些功能。下面是 pandasPythonNumpy的数据类型列表,对比你就发现pandas的数据类型是有很大优化空间的。


Pandas dtype Python type NumPy type Usage
object str string_,unicode Text
int64 int int,int8,intl6,int32,int64,uint8,uint16,uint32,uint64 Integer numbers
float64 float float,float16,float32,float64 Floating point numbers
bool bool bool_ True/False values
datetime64 NA datetime64[ns] Date and time values
timedelta[ns] NA NA Differences between two datetimes
category NA NA Finite list of text values

来源:http : //pbpython.com/pandas_dtypes.html


很多默认的数据类型占用很多内存空间,其实根据没有必要,我们完全可以压缩到可能小的子类型。


Data type Description
bool_ Boolean(True or False) stored as a byte
int_ Default integer type(same as C 1ong ; normally either int64or int32)
intc ldentical to C int(normally int32 or int64)
intp Integer used for indexing(same as C ssize_t; normally either int32 or int64)
int 8Byte(-128 to 127)
int16 Integer(-32768 to 32767)
int32 Integer(-2147483648 to 2147483647)
int64 Integer(-9223372036854775808 to 9223372036854775807)
uint8 Unsigned integer(0 to 255)
uint16 Unsigned integer(0 to 65535)
uint32 Unsigned integer(0 to 4294967295)
uint64 Unsigned integer(0 to 18446744073709551615)
float_ Shorthand for float64.
float16 Half precision float: sign bit,5 bits exponent,10 bits mantissa
float32 Single precision float: sign bit,8 bits exponent,23 bits mantissa
float64 Double precision float: sign bit,11 bits exponent,52 bits mantissa
complex_ Shorthand for complex128.
complex64 Complex number, represented by two 32-bit floats(real and imaginary components)
complex128 Complex number, represented by two 64-bit floats(real and imaginary components)

来源:https : //docs.scipy.org/doc/numpy-1.13.0/user/basics.types.html


上面是scipy文档中列出的所有数据类型,从简单到复杂。我们希望将类型简单化,以此节省内存,比如将浮点数转换为float16/32,或者将具有正整数和负整数的列转为int8/16/32,还可以将布尔值转换为uint8,甚至仅使用正整数来进一步减少内存消耗。

基于上面所说的变量类型简化的思考,写出一个自动转化的函数,它可以根据上表将浮点数和整数转换为它们的最小子类型


def reduce_memory_usage(df, verbose=True):
    numerics = ["int8", "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 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
    if verbose:
        print(
            "Mem. usage decreased to {:.2f} Mb ({:.1f}% reduction)".format(
                end_mem, 100 * (start_mem - end_mem) / start_mem
            )
        )
    return df


当然,这个函数不是固定,东哥只是提供个模板,大家可以直接复制拿过去改成自己习惯的方式。

下面来看一下这个转化函数能给我们具体带来多少内存占用的减少。这里我用了一个加载进来会占用2.2GB内存的数据集,使用reduce_memory_usage以后的情况是这样的。


>>> reduce_memory_usage(tps_october)
Mem. usage decreased to 509.26 Mb (76.9% reduction)


数据集的内存占用从原来的 2.2GB 压缩到 510MB。不要小看这个压缩量,因为数据分析或者建模的过程中,要做很多数据处理操作,就这导致数据集会被重复使用很多次。如果开始的数据集就很大,那么后面的内存占用也会跟着大,这样一算下来整个就放大了很多倍。


但有一点需要提示一下,尽管在我们运行时会减少内存,但当我们保存数据时,内存减少的效果会丢失掉,不过磁盘空间往往是够用的,这个影响没那么大。

原创不易,欢迎点赞、留言、分享,支持我继续写下去


相关文章
|
23天前
|
Java Android开发 UED
安卓应用开发中的内存管理优化技巧
在安卓开发的广阔天地里,内存管理是一块让开发者既爱又恨的领域。它如同一位严苛的考官,时刻考验着开发者的智慧与耐心。然而,只要我们掌握了正确的优化技巧,就能够驯服这位考官,让我们的应用在性能和用户体验上更上一层楼。本文将带你走进内存管理的迷宫,用通俗易懂的语言解读那些看似复杂的优化策略,让你的开发之路更加顺畅。
32 2
|
2月前
|
存储 缓存 JSON
一行代码,我优化掉了1G内存占用
这里一行代码,指的是:String.intern()的调用,为了调用这一行代码,也写了几十行额外的代码。
|
2月前
|
机器学习/深度学习 数据采集 PyTorch
构建高效 PyTorch 模型:内存管理和优化技巧
【8月更文第27天】PyTorch 是一个强大的深度学习框架,被广泛用于构建复杂的神经网络模型。然而,在处理大规模数据集或使用高性能 GPU 进行训练时,有效的内存管理对于提升模型训练效率至关重要。本文将探讨如何在 PyTorch 中有效地管理内存,并提供一些优化技巧及代码示例。
48 1
|
2月前
|
Linux 测试技术 C++
内存管理优化:内存泄漏检测与预防。
内存管理优化:内存泄漏检测与预防。
44 2
|
21天前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
42 0
|
2月前
|
关系型数据库 MySQL
MySQl优化:使用 jemalloc 分配内存
MySQl优化:使用 jemalloc 分配内存
|
3月前
|
缓存 算法 Java
探索现代操作系统中的内存管理优化策略
【7月更文挑战第24天】本文深入探讨了现代操作系统中内存管理的高级技术与优化策略。通过分析内存分配、虚拟内存机制以及缓存策略,文章揭示了如何提升系统性能和资源利用率。针对操作系统开发者和高级用户,本文提供了实用的调优技巧和未来的发展方向。
|
2月前
|
监控 Java
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
80 0
|
2月前
|
存储 Go
Go 内存分配:结构体中的优化技巧
Go 内存分配:结构体中的优化技巧
|
3月前
|
机器学习/深度学习 数据采集 数据处理
重构数据处理流程:Pandas与NumPy高级特性在机器学习前的优化
【7月更文挑战第14天】在数据科学中,Pandas和NumPy是数据处理的关键,用于清洗、转换和计算。用`pip install pandas numpy`安装后,Pandas的`read_csv`读取数据,`fillna`处理缺失值,`drop`删除列。Pandas的`apply`、`groupby`和`merge`执行复杂转换。NumPy加速数值计算,如`square`进行向量化操作,`dot`做矩阵乘法。结合两者优化数据预处理,提升模型训练效率和效果。
48 1

热门文章

最新文章

相关实验场景

更多
下一篇
无影云桌面