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

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

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

固然.itertuples每每会更快一些,可是在这个例子中行使.iterrows,我们看看这行使iterrows后结果怎样。

  1. >>> @timeit(repeat=3, number=100) 
  2. ... def apply_tariff_iterrows(df): 
  3. ...     energy_cost_list = [] 
  4. ...     for index, row in df.iterrows(): 
  5. ...         # 获取用电量和时刻(小时) 
  6. ...         energy_used = row['energy_kwh'] 
  7. ...         hour = row['date_time'].hour 
  8. ...         # 添加cost列表 
  9. ...         energy_cost = apply_tariff(energy_used, hour) 
  10. ...         energy_cost_list.append(energy_cost) 
  11. ...     df['cost_cents'] = energy_cost_list 
  12. ... 
  13. >>> apply_tariff_iterrows(df) 
  14. Best of 3 trials with 100 function calls per trial: 
  15. Function `apply_tariff_iterrows` ran in average of 0.713 seconds. 

语法方面:这样的语法更明晰,而且行值引用中的紊乱更少,因此它更具可读性。

在时刻收益方面:快了近5倍! 可是,尚有更多的改造空间。我们如故在行使某种情势的Python for轮回,,这意味着每个函数挪用都是在Python中完成的,抱负环境是它可以用Pandas内部架构中内置的更快的说话完成。

Pandas的 .apply()要领

我们可以行使.apply要领而不是.iterrows进一步改造此操纵。Pandas的.apply要领接管函数(callables)并沿DataFrame的轴(全部行或全部列)应用它们。在此示例中,lambda函数将辅佐你将两列数据转达给apply_tariff():

  1. >>> @timeit(repeat=3, number=100) 
  2. ... def apply_tariff_withapply(df): 
  3. ...     df['cost_cents'] = df.apply( 
  4. ...         lambda row: apply_tariff( 
  5. ...             kwh=row['energy_kwh'], 
  6. ...             hour=row['date_time'].hour), 
  7. ...         axis=1) 
  8. ... 
  9. >>> apply_tariff_withapply(df) 
  10. Best of 3 trials with 100 function calls per trial: 
  11. Function `apply_tariff_withapply` ran in average of 0.272 seconds. 

.apply的语法利益很明明,行数少,代码可读性高。在这种环境下,所耗费的时刻约莫是.iterrows要领的一半。

可是,这还不是“很是快”。一个缘故起因是.apply()将在内部实行轮回遍历Cython迭代器。可是在这种环境下,转达的lambda不是可以在Cython中处理赏罚的对象,因此它在Python中挪用,因此并不是那么快。

假如你行使.apply()获取10年的小时数据,那么你将必要约莫15分钟的处理赏罚时刻。假如这个计较只是大型模子的一小部门,那么你真的应该加速速率。这也就是矢量化操纵派上用场的处所。

矢量化操纵:行使.isin()选择数据

什么是矢量化操纵?假如你不基于一些前提,而是可以在一行代码中将全部电力耗损数据应用于该价值(df ['energy_kwh'] * 28),相同这种。这个特定的操纵就是矢量化操纵的一个例子,它是在Pandas中执行的最将近领。

可是怎样将前提计较应用为Pandas中的矢量化运算?一个能力是按照你的前提选择和分组DataFrame,然后对每个选定的组应用矢量化操纵。 在下一个示例中,你将看到怎样行使Pandas的.isin()要领选择行,然后在向量化操纵中实现上面新特性的添加。在执行此操纵之前,假如将date_time列配置为DataFrame的索引,则会使工作更利便:

  1. df.set_index('date_time', inplace=True) 
  2.  
  3. @timeit(repeat=3, number=100) 
  4. def apply_tariff_isin(df): 
  5.     # 界说小时范畴Boolean数组 
  6.     peak_hours = df.index.hour.isin(range(17, 24)) 
  7.     shoulder_hours = df.index.hour.isin(range(7, 17)) 
  8.     off_peak_hours = df.index.hour.isin(range(0, 7)) 
  9.  
  10.     # 行使上面的界说 
  11.     df.loc[peak_hours, 'cost_cents'] = df.loc[peak_hours, 'energy_kwh'] * 28 
  12.     df.loc[shoulder_hours,'cost_cents'] = df.loc[shoulder_hours, 'energy_kwh'] * 20 
  13.     df.loc[off_peak_hours,'cost_cents'] = df.loc[off_peak_hours, 'energy_kwh'] * 12 

(编辑:湖南网)

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

热点阅读