使用大型数据集时如何优化熊猫(论文)

当旅行车和/或小型数据集的内存可以安全地扔入熊猫而无需任何优化时。 但是,如果数据很大,则会出现如何处理或至少计数的问题。

建议以缩影看待优化,以免从网络中提取巨型数据集。

作为数据集,我们将结合使用habrastatistics和2019年的用户评论,这要归功于一位辛勤的用户:
资料集

作为信息基础,将使用Habr先前翻译的文章 ,其中混合了很多有趣的东西。

而不是加入


尽管habrastatistics数据集占用288 MB且包含448,533行,但被认为很小。
当然,您可以找到更多数据,但是为了不挂车,让我们继续研究。

为了方便操作,我们将添加列名(只需将第一行写到文件中):

a,b,c,d 

现在,如果您直接将数据集加载到熊猫中并检查其使用了多少内存

 import os import time import pandas as pd import numpy as np gl = pd.read_csv('habr_2019_comments.csv',encoding='UTF') def mem_usage(pandas_obj): if isinstance(pandas_obj,pd.DataFrame): usage_b = pandas_obj.memory_usage(deep=True).sum() else: #     ,     DataFrame,   Series usage_b = pandas_obj.memory_usage(deep=True) usage_mb = usage_b / 1024 ** 2 #     return "{:03.2f} MB".format(usage_mb) print (gl.info(memory_usage='deep')) 

看到他“吃”了436.1 MB:

 RangeIndex: 448533 entries, 0 to 448532 Data columns (total 4 columns): a 448533 non-null object b 448533 non-null object c 448533 non-null object d 448528 non-null object dtypes: object(4) memory usage: 436.1 MB 

它还表明我们正在处理包含对象类型数据的列。
因此,根据该文章 ,对于列,有必要将重点放在为对象计算的优化上。 对于除一列外的所有列。

b列包含日期,为了便于进一步计算和清楚起见,最好将它们发送到数据集的索引。 为此,请更改读取数据集时使用的代码:

 gl = pd.read_csv('habr_2019_comments.csv', parse_dates=['b'], encoding='UTF') 

现在,将日期作为数据集的索引读取,并且内存消耗略有减少:

 memory usage: 407.0 MB 

现在我们在列和索引之外的数据集中优化数据


优化称为:“使用分类变量优化对象类型的数据存储”。

如果将其翻译成俄文,那么我们需要按类别合并列中的数据,以使其生效。

要确定有效性,您需要知道列中唯一值的数量,如果该值少于列中值总数的50%,则将类别中的值组合起来将是有效的。

让我们看一下数据集:

 gl_obj=gl.select_dtypes(include=['object']).copy() gl_obj.describe() 

  acd count 448533 448533 448528 unique 25100 185 447059 top VolCh 0 ! freq 3377 260438 184 

*列中有日期且未显示的日期

如您所见,在唯一行的ac列中,类别中的联合有效。 对于列a,这是25100个用户(显然小于448533),对于c-185个带有“ +”和“-”的比例值(也明显小于448533)。

我们优化列:

 for col in gl_obj.columns: num_unique_values = len(gl_obj[col].unique()) num_total_values = len(gl_obj[col]) if num_unique_values / num_total_values < 0.5: converted_obj.loc[:,col] = gl_obj[col].astype('category') else: converted_obj.loc[:,col] = gl_obj[col] 

为了了解为方便起见使用了多少内存,我们引入一个函数:

 def mem_usage(pandas_obj): if isinstance(pandas_obj,pd.DataFrame): usage_b = pandas_obj.memory_usage(deep=True).sum() else: #     ,     DataFrame,   Series usage_b = pandas_obj.memory_usage(deep=True) usage_mb = usage_b / 1024 ** 2 #     return "{:03.2f} MB".format(usage_mb) 

并检查优化是否有效:

 >>> print('  : '+mem_usage(gl_obj))   : 407.14 MB >>> print('  : '+mem_usage(converted_obj))   : 356.40 MB >>> 

如您所见,又获得了50 MB的增益。

现在,了解优化已受益(它会发生,反之亦然),我们将在读取时设置数据集参数,以便立即考虑我们正在处理的数据:

 gl = pd.read_csv('habr_2019_comments.csv', parse_dates=['b'],index_col='b',dtype ={'c':'category','a':'category','d':'object'}, encoding='UTF') 

我们希望您能快速使用数据集!

下载代码在这里

Source: https://habr.com/ru/post/zh-CN467785/


All Articles