解决 pandas 读取数据时内存过大的问题

举报
毛利 发表于 2021/07/15 02:16:27 2021/07/15
【摘要】 解决 pandas 读取数据时内存过大的问题 背景: 在我们使用pandas进行数据处理的时候,有时候发现文件在本地明明不大,但是用pandas以DataFrame形式加载内存中的时候会占用非常高的内存,这是因为pandas的处理机制默认会按照最大的规格去设置数据类型。 数据类型占用内存表格 常用的数据类型范围如下所示: dtypes 范围下限(含) 范围上限...

解决 pandas 读取数据时内存过大的问题

背景:

在我们使用pandas进行数据处理的时候,有时候发现文件在本地明明不大,但是用pandas以DataFrame形式加载内存中的时候会占用非常高的内存,这是因为pandas的处理机制默认会按照最大的规格去设置数据类型。

数据类型占用内存表格

  • 常用的数据类型范围如下所示:

    dtypes 范围下限(含) 范围上限(含)
    unit8 0 255
    unit16 0 65535
    int8 -128 127
    int16 -32768 32767
    int32 -2147483648 2147483647
    int64 –9,223,372,036,854,775,808 9,223,372,036,854,775,807
    
        
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

案例展示:

  • 制造数据:

    data = {'player1':[70,75,60,68]}
    
    data = pd.DataFrame(data)
    data player1
      0	70
      1	75
      2	60
      3	68
    
        
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 输出数据和他的数据类型:

    for i in data['player1'].values: print(type(i))
    
    <class 'numpy.int64'>
    <class 'numpy.int64'>
    <class 'numpy.int64'>
    <class 'numpy.int64'>
    
        
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

解决方法:

def reduce_mem_usage(df, verbose=True): numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64'] # 计算当前占用的内存 start_mem = df.memory_usage(deep=True).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() # 如果 该列的数据类型属于 int 类型,然后进行判断 if str(col_type)[:3] == 'int': # 如果 该列最小的值 大于int8类型的最小值,并且最大值小于int8类型的最大值,则采用int8类型 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) # 否则 则采用 float 的处理方法 else: if 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(deep=True).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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。

原文链接:maoli.blog.csdn.net/article/details/115801785

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。