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

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

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

1.61s,看上去挺快,但着实可以更快,我们来看一下下面的要领。

  1. >>> @timeit(repeat=3, number=100) 
  2. >>> def convert_with_format(df, column_name): 
  3. ...     return pd.to_datetime(df[column_name], 
  4. ...                           format='%d/%m/%y %H:%M') 
  5. Best of 3 trials with 100 function calls per trial: 
  6. Function `convert_with_format` ran in average of 0.032 seconds. 

功效只有0.032s,快了快要50倍。缘故起因是:我们配置了转化的名目format。因为在CSV中的datetimes并不是 ISO 8601 名目标,假如不举办配置的话,那么pandas将行使 dateutil 包把每个字符串str转化成date日期。

相反,假如原始数据datetime已经是 ISO 8601 名目了,那么pandas就可以当纵然用最快速的要领来理会日期。这也就是为什么提前配置好名目format可以晋升这么多。

pandas数据的轮回操纵

如故基于上面的数据,我们想添加一个新的特性,但这个新的特性是基于一些时刻前提的,按照时长(小时)而变革,如下:

还在诉苦Pandas运行速率慢?这几个要了解倾覆你的观点

因此,凭证我们正常的做法就是行使apply要领写一个函数,函数内里写好时刻前提的逻辑代码。

  1. def apply_tariff(kwh, hour): 
  2.     """计较每个小时的电费"""     
  3.     if 0 <= hour < 7: 
  4.         rate = 12 
  5.     elif 7 <= hour < 17: 
  6.         rate = 20 
  7.     elif 17 <= hour < 24: 
  8.         rate = 28 
  9.     else: 
  10.         raise ValueError(f'Invalid hour: {hour}') 
  11.     return rate * kwh 

然后行使for轮回来遍历df,按照apply函数逻辑添加新的特性,如下:

  1. >>> # 不拥护这种操纵 
  2. >>> @timeit(repeat=3, number=100) 
  3. ... def apply_tariff_loop(df): 
  4. ...     """Calculate costs in loop.  Modifies `df` inplace.""" 
  5. ...     energy_cost_list = [] 
  6. ...     for i in range(len(df)): 
  7. ...         # 获取用电量和时刻(小时) 
  8. ...         energy_used = df.iloc[i]['energy_kwh'] 
  9. ...         hour = df.iloc[i]['date_time'].hour 
  10. ...         energy_cost = apply_tariff(energy_used, hour) 
  11. ...         energy_cost_list.append(energy_cost) 
  12. ...     df['cost_cents'] = energy_cost_list 
  13. ...  
  14. >>> apply_tariff_loop(df) 
  15. Best of 3 trials with 100 function calls per trial: 
  16. Function `apply_tariff_loop` ran in average of 3.152 seconds. 

对付那些写Pythonic气魄威风凛凛的人来说,这个计划看起来很天然。然而,这个轮回将会严峻影响服从,也是不拥护这么做。缘故起因有几个:

  • 起首,它必要初始化一个将记录输出的列表。
  • 其次,它行使不透明工具范畴(0,len(df))轮回,然后在应用apply_tariff()之后,它必需将功效附加到用于建设新DataFrame列的列表中。它还行使df.iloc [i] ['date_time']执行所谓的链式索引,这凡是会导请安外的功效。
  • 但这种要领的最大题目是计较的时刻本钱。对付8760行数据,此轮回耗费了3秒钟。接下来,你将看到一些改造的Pandas布局迭代办理方案。

行使itertuples() 和iterrows() 轮回

那么保举做法是什么样的呢?

现实上可以通过pandas引入itertuples和iterrows要领可以使服从更快。这些都是一次发生一行的天生器要领,相同scrapy中行使的yield用法。

.itertuples为每一行发生一个namedtuple,而且行的索引值作为元组的第一个元素。nametuple是Python的collections模块中的一种数据布局,其举动相同于Python元组,但具有可通过属性查找会见的字段。

.iterrows为DataFrame中的每一行发生(index,series)这样的元组。

(编辑:湖南网)

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

热点阅读