1.61s,看上去挺快,但着实可以更快,我们来看一下下面的要领。
- >>> @timeit(repeat=3, number=100)
- >>> def convert_with_format(df, column_name):
- ... return pd.to_datetime(df[column_name],
- ... format='%d/%m/%y %H:%M')
- Best of 3 trials with 100 function calls per trial:
- 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数据的轮回操纵
如故基于上面的数据,我们想添加一个新的特性,但这个新的特性是基于一些时刻前提的,按照时长(小时)而变革,如下:

因此,凭证我们正常的做法就是行使apply要领写一个函数,函数内里写好时刻前提的逻辑代码。
- def apply_tariff(kwh, hour):
- """计较每个小时的电费"""
- if 0 <= hour < 7:
- rate = 12
- elif 7 <= hour < 17:
- rate = 20
- elif 17 <= hour < 24:
- rate = 28
- else:
- raise ValueError(f'Invalid hour: {hour}')
- return rate * kwh
然后行使for轮回来遍历df,按照apply函数逻辑添加新的特性,如下:
- >>> # 不拥护这种操纵
- >>> @timeit(repeat=3, number=100)
- ... def apply_tariff_loop(df):
- ... """Calculate costs in loop. Modifies `df` inplace."""
- ... energy_cost_list = []
- ... for i in range(len(df)):
- ... # 获取用电量和时刻(小时)
- ... energy_used = df.iloc[i]['energy_kwh']
- ... hour = df.iloc[i]['date_time'].hour
- ... energy_cost = apply_tariff(energy_used, hour)
- ... energy_cost_list.append(energy_cost)
- ... df['cost_cents'] = energy_cost_list
- ...
- >>> apply_tariff_loop(df)
- Best of 3 trials with 100 function calls per trial:
- 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)这样的元组。 (编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|