pandas 速度,pandas处理数据很慢
熊猫的数据处理效率还是很优秀的。相对于大规模数据集,只要掌握正确的方法,在数据处理上可以节省很多时间。本文为大家总结了一些熊猫数据处理加速技巧,有需要的可以参考。
00-1010数据准备日期时间数据优化数据简单循环。itertuples()和。iterrows()方法。apply()方法。isin()数据选择。cut()数据宁滨Numpy方法处理效率对比HDFStore防止重新处理熊猫处理数据的效率还是很优秀的。相对于大规模数据集,只要掌握正确的方法,就可以
Pandas是建立在NumPy数组结构上的,很多操作都是用C来执行的,要么通过NumPy,要么通过Pandas自己的Python扩展模块库。这些模块都是用Cython写的,编译成c,理论上处理速度应该很快。
那么为什么同样的数据由两个人处理,在设备相同的情况下,处理时间却相差很大呢?
需要澄清的是,这不是一个关于如何过度优化Pandas代码的指南。如果使用得当,熊猫会跑得很快。此外,优化和编写干净的代码有很大的区别。
这是一个在Python中使用Pandas的指南,以充分利用其强大且易于使用的内置特性。
目录
本例的目的是应用分时电价来计算一年的总能耗成本。也就是说,在一天中的不同时间,电价会有所不同,所以任务是将每小时消耗的电力乘以消耗该小时的正确价格。
从一个包含两列的CSV文件中读取数据,一列是日期和时间,另一列是功耗(千瓦时)。
数据准备
进口熊猫作为pd
Df=pd.read_csv(数据科学必备的熊猫实用数据处理加速技巧总结/demand_profile.csv )
df.head()
日期时间能量千瓦时
0 1/1/13 0:00 0.586
1 1/1/13 1:00 0.580
2 1/1/13 2:00 0.572
3 1/1/13 3:00 0.596
4 1/1/13 4:00 0.592
乍一看,这看起来不错,但有一个小问题。Pandas和NumPy有一个dtypes(数据类型)的概念。如果没有指定参数,date_time将采用object dtype。
df.dtypes
日期时间对象
能量_千瓦时浮动64
dtype:对象
type(df.iat[0,0])
潜艇用热中子反应堆(submarine thermal reactor的缩写)
对象不仅是str的容器,也是任何不能完全适合一种数据类型的列的容器。把日期当成字符串会很费力,效率很低(也会导致记忆效率低下)。为了处理时间序列数据,需要将date_time列格式化为日期-时间对象数组(时间戳)。
df[日期时间]=pd.to_datetime(df[日期时间])
df[日期时间]。类型
日期时间64[纳秒]
现在有一个名为df的数据帧,它有两列和一个用于引用行的数字索引。
df.head()
日期时间能量千瓦时
0 2013-01-01 00:00:00 0.586
1 2013-01-01 01:00:00 0.580
2 2013-01-01 02:00:00 0.572
3 2013-01-01 03:00:00 0.596
4 2013-01-01 04:00:00 0.592
使用Jupyter自己的%%time timing装饰器进行测试。
ss="brush:py;">def convert(df, column_name):
return pd.to_datetime(df[column_name])
%%time
df[date_time] = convert(df, date_time)
Wall time: 663 ms
def convert_with_format(df, column_name):
return pd.to_datetime(df[column_name],format=%d/%m/%y %H:%M)
%%time
df[date_time] = convert(df, date_time)
Wall time: 1.99 ms
处理效率提高将近350倍。如果在处理大规模数据的情况下,处理数据的时间会无限的放大。
数据的简单循环
既然日期和时间格式处理完毕,就可以着手计算电费了。成本因小时而异,因此需要有条件地将成本因素应用于一天中的每个小时。
在此示例中,使用时间成本将定义成三个部分。
data_type = {
如果价格是一天中每小时每千瓦时 28 美分。
df['cost_cents'] = df['energy_kwh'] * 28
date_time energy_kwh cost_cents
但是成本计算取决于一天中的不同时间。这就是你会看到很多人以意想不到的方式使用 Pandas 的地方,通过编写一个循环来进行条件计算。
def apply_tariff(kwh, hour):
循环 .itertuples() 和 .iterrows() 方法
Pandas 实际上 for i in range(len(df)) 通过引入 DataFrame.itertuples() 和 DataFrame.iterrows() 方法使语法就可能显得多余,这些都是yield一次一行的生成器方法。
.itertuples() 为每一行生成一个命名元组,行的索引值作为元组的第一个元素。 名称元组是来自 Python 集合模块的数据结构,其行为类似于 Python 元组,但具有可通过属性查找访问的字段。
.iterrows() 为 DataFrame 中的每一行生成 (index, Series) 对(元组)。
def apply_tariff_iterrows(df):
速度提高又3倍之多。
.apply() 方法
可以使用 .apply() 方法进一步改进此操作。 Pandas 的 .apply() 方法采用函数(可调用对象)并将它们沿 DataFrame 的轴(所有行或所有列)应用。
lambda 函数将两列数据传递给 apply_tariff()。
def apply_tariff_withapply(df):
.apply() 的语法优势很明显,代码简洁、易读、明确。在这种情况下所用时间大约是该 .iterrows() 方法的4分之一。
.isin() 数据选择
但是如何在 Pandas 中将条件计算应用为矢量化操作呢?一个技巧是根据的条件选择和分组 DataFrame 的部分,然后对每个选定的组应用矢量化操作。
使用 Pandas 的.isin()方法选择行,然后在矢量化操作中应用。在执行此操作之前,如果将 date_time 列设置为 DataFrame 的索引会更方便。
df.set_index(date_time, inplace=True)
其中整个过程方法返回一个布尔列表。
[False, False, False, ..., True, True, True]
.cut() 数据分箱
设置时间切分的列表和对那个计算的函数公式,让操作起来更简单,但是这个对于新手来说代码阅读起来有些困难。
def apply_tariff_cut(df):
Numpy 方法处理
Pandas Series 和 DataFrames 是在 NumPy 库之上设计的。这为提供了更大的计算灵活性,因为 Pandas 可以与 NumPy 数组和操作无缝协作。
使用 NumPy 的digitize()函数。它与 Pandas 的相似之处cut()在于数据将被分箱,但这次它将由一个索引数组表示,该数组表示每个小时属于哪个箱。然后将这些索引应用于价格数组。
import numpy as np
处理效率比较
对比一下上面几种不同的处理方式的效率吧。
功能运行时间(秒)apply_tariff_loop()2.59 sapply_tariff_iterrows()808 msapply_tariff_withapply()181 msapply_tariff_isin()53.5 msapply_tariff_cut()2.99 msapply_tariff_digitize()1.99 ms
HDFStore 防止重新处理
通常构建复杂的数据模型时,对数据进行一些预处理会很方便。如果有 10 年的分钟频率用电量数据,即指定了格式参数简单地将日期和时间转换为日期时间也可能需要 20 分钟。只需要这样做一次而不是每次运行模型时都需要进行测试或分析。
可以在这里做的一件非常有用的事情是预处理,然后以处理后的形式存储数据,以便在需要时使用。但是如何才能以正确的格式存储数据而无需再次重新处理呢?如果要保存为 CSV 只会丢失您的日期时间对象,并且在再次访问时必须重新处理它。
Pandas 有一个内置的解决方案使用 HDF5,一种专为存储表格数据数组而设计的高性能存储格式。Pandas 的 HDFStore 类允许将 DataFrame 存储在 HDF5 文件中,以便可以有效地访问它,同时仍保留列类型和其他元数据。dict 是一个类似字典的类,因此可以像对 Python对象一样进行读写。
将预处理的耗电量 DataFrame 存储df在 HDF5 文件中。
data_store = pd.HDFStore(processed_data.h5)
从 HDF5 文件访问数据的方法,并保留数据类型。
data_store = pd.HDFStore(processed_data.h5)
到此这篇关于Pandas数据处理加速技巧汇总的文章就介绍到这了,更多相关Pandas数据处理内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。