固然.itertuples每每会更快一些,可是在这个例子中行使.iterrows,我们看看这行使iterrows后结果怎样。
- >>> @timeit(repeat=3, number=100)
- ... def apply_tariff_iterrows(df):
- ... energy_cost_list = []
- ... for index, row in df.iterrows():
- ... # 获取用电量和时刻(小时)
- ... energy_used = row['energy_kwh']
- ... hour = row['date_time'].hour
- ... # 添加cost列表
- ... energy_cost = apply_tariff(energy_used, hour)
- ... energy_cost_list.append(energy_cost)
- ... df['cost_cents'] = energy_cost_list
- ...
- >>> apply_tariff_iterrows(df)
- Best of 3 trials with 100 function calls per trial:
- 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():
- >>> @timeit(repeat=3, number=100)
- ... def apply_tariff_withapply(df):
- ... df['cost_cents'] = df.apply(
- ... lambda row: apply_tariff(
- ... kwh=row['energy_kwh'],
- ... hour=row['date_time'].hour),
- ... axis=1)
- ...
- >>> apply_tariff_withapply(df)
- Best of 3 trials with 100 function calls per trial:
- 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的索引,则会使工作更利便:
- df.set_index('date_time', inplace=True)
-
- @timeit(repeat=3, number=100)
- def apply_tariff_isin(df):
- # 界说小时范畴Boolean数组
- peak_hours = df.index.hour.isin(range(17, 24))
- shoulder_hours = df.index.hour.isin(range(7, 17))
- off_peak_hours = df.index.hour.isin(range(0, 7))
-
- # 行使上面的界说
- df.loc[peak_hours, 'cost_cents'] = df.loc[peak_hours, 'energy_kwh'] * 28
- df.loc[shoulder_hours,'cost_cents'] = df.loc[shoulder_hours, 'energy_kwh'] * 20
- df.loc[off_peak_hours,'cost_cents'] = df.loc[off_peak_hours, 'energy_kwh'] * 12
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|