• 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时, 内存会明显被节省。

  • 相关阅读:
    Codeforces 1291 Round #616 (Div. 2) B
    总结
    刷新DNS解析缓存+追踪+域名解析命令
    数学--数论--Hdu 5793 A Boring Question (打表+逆元)
    Lucene.net(4.8.0) 学习问题记录六:Lucene 的索引系统和搜索过程分析
    LeetCode 117 Populating Next Right Pointers in Each Node II
    LeetCode 116 Populating Next Right Pointers in Each Node
    test test
    LeetCode 115 Distinct Subsequences
    LeetCode 114. Flatten Binary Tree to Linked List
  • 原文地址:https://www.cnblogs.com/dudumiaomiao/p/12902718.html
Copyright © 2020-2023  润新知