加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

还在抱怨Pandas运行速度慢?这几个方法会颠覆你的看法

发布时间:2019-01-04 07:02:11 所属栏目:教程 来源:知乎
导读:媒介 当各人谈到数据说明时,说起最多的说话就是Python和SQL。Python之以是得当数据说明,是由于它有许多第三方强盛的库来帮忙,pandas就是个中之一。pandas的文档中是这样描写的: 快速,机动,富有示意力的数据布局,旨在使相关或标志数据的行使既简朴又

我们来看一下功效怎样。

  1. >>> apply_tariff_isin(df) 
  2. Best of 3 trials with 100 function calls per trial: 
  3. Function `apply_tariff_isin` ran in average of 0.010 seconds. 

为了相识适才代码中产生的环境,我们必要知道.isin()要领返回的是一个布尔值数组,如下所示:

  1. [False, False, False, ..., True, True, True] 

这些值标识哪些DataFrame索引(datetimes)落在指定的小时范畴内。然后,当你将这些布尔数组转达给DataFrame的.loc索引器时,你将得到一个仅包括与这些小时匹配的行的DataFrame切片。在那之后,仅仅是将切片乘以恰当的费率,这是一种快速的矢量化操纵。

这与我们上面的轮回操纵对比怎样?起首,你也许会留意到不再必要apply_tariff(),由于全部前提逻辑都应用于行的选择。因此,你必需编写的代码行和挪用的Python代码会大大镌汰。

处理赏罚时刻怎么样?比不是Pythonic的轮回快315倍,比.iterrows快71倍,比.apply快27倍。

还可以做的更好吗?

在apply_tariff_isin中,我们如故可以通过挪用df.loc和df.index.hour.isin三次来举办一些“手动事变”。假如我们有更风雅的时隙范畴,你也许会争冲突这个办理方案是不行扩展的。荣幸的是,在这种环境下,你可以行使Pandas的pd.cut() 函数以编程方法执行更多操纵:

  1. @timeit(repeat=3, number=100) 
  2. def apply_tariff_cut(df): 
  3.     cents_per_kwh = pd.cut(x=df.index.hour, 
  4.                            bins=[0, 7, 17, 24], 
  5.                            include_lowest=True, 
  6.                            labels=[12, 20, 28]).astype(int) 
  7.     df['cost_cents'] = cents_per_kwh * df['energy_kwh'] 

让我们看看这里产生了什么。pd.cut() 按照每小时所属的bin应用一组标签(costs)。

  • 留意include_lowest参数暗示第一个隔断是否应该是包括左边的(您但愿在组中包括时刻= 0)。

这是一种完全矢量化的方法来得到我们的预期功效,它在时刻方面是最快的:

  1. >>> apply_tariff_cut(df) 
  2. Best of 3 trials with 100 function calls per trial: 
  3. Function `apply_tariff_cut` ran in average of 0.003 seconds. 

到今朝为止,时刻上根基快到达极限了,只必要耗费不到一秒的时刻来处理赏罚完备的10年的小时数据集。可是,最后一个选项是行使 NumPy 函数来操纵每个DataFrame的底层NumPy数组,然后将功效集成回Pandas数据布局中。

行使Numpy继承加快

行使Pandas时不该健忘的一点是Pandas Series和DataFrames是在NumPy库之上计划的。这为你提供了更多的计较机动性,由于Pandas可以与NumPy阵列和操纵无缝跟尾。

下面,我们将行使NumPy的 digitize() 函数。它相同于Pandas的cut(),由于数据将被分箱,但这次它将由一个索引数组暗示,这些索引暗示每小时所属的bin。然后将这些索引应用于价值数组:

  1. @timeit(repeat=3, number=100) 
  2. def apply_tariff_digitize(df): 
  3.     prices = np.array([12, 20, 28]) 
  4.     bins = np.digitize(df.index.hour.values, bins=[7, 17, 24]) 
  5.     df['cost_cents'] = prices[bins] * df['energy_kwh'].values 

与cut函数一样,这种语法很是简捷易读。但它在速率方面有何较量?让我们来看看:

  1. >>> apply_tariff_digitize(df) 
  2. Best of 3 trials with 100 function calls per trial: 
  3. Function `apply_tariff_digitize` ran in average of 0.002 seconds. 

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读