我正在做一个半小时的分组约会,并申请在我的数据集上计算每日统计信息,但是速度很慢。有没有一种方法可以改善以下功能的性能?我已经读过关于向量化的知识,但不确定如何实现。
我已经使用了apply和transform来获得所需的输出,但是整整一年的数据大约需要2-3秒,我希望能更快地完成,因为我有很多数据。任何人都可以指出正确的方向吗?
import pandas as pd
import numpy as np
import timeit
# dummy data
date_range = pd.date_range('2017-01-01 00:00', '2018-01-01 00:00', freq='30Min')
df = pd.DataFrame(np.random.randint(2, 20, (date_range.shape[0], 2)), index=date_range, columns=['Electricity', 'Natural Gas'])
print(df.head())
print(df.shape)
t1 = timeit.default_timer()
onhour = df.groupby([pd.Grouper(freq='D')]).apply(lambda x: np.count_nonzero(
x[x > x.quantile(0.05) + x.mean() * .1] >
x.quantile(0.05) + 0.25 * (x.quantile(0.95)-x.quantile(0.05)),
axis=0) / 2)
onhour = pd.DataFrame(
onhour.values.tolist(),
index=onhour.index,
columns=df.columns)
print(f"start_time in {timeit.default_timer() - t1}")
print(onhour.head())
t1 = timeit.default_timer()
onhour = df.groupby([pd.Grouper(freq='D')]).transform(lambda x: np.count_nonzero(
x[x > x.quantile(0.05) + x.mean() * .1] >
x.quantile(0.05) + 0.25 * (x.quantile(0.95)-x.quantile(0.05)),
axis=0) / 2).resample('D').mean()
print(f"start_time in {timeit.default_timer() - t1}")
print(onhour.head())
答案 0 :(得分:2)
您已经在使用熊猫矢量化优化,因此您不会花费很多时间,但是一些技巧可以使您在1.5秒内获得成功。
1)使用agg
使用agg
代替transform
或apply
会得到更好的结果,因为you have the same computation for each column (electricity & gas)。
2)保存分位数计算。
您正在计算5%分位数的3倍。我使用的是Python function
而不是lambda
,如果您添加了记忆化的分位数功能,它仍然可以使用lambda(它实际上可以帮助固定,但我敢肯定)。
def count_something(row):
qt_df = row.quantile([0.05, 0.95])
return np.count_nonzero(
row[row > qt_df.loc[0.05] + row.mean() * .1] > qt_df.loc[0.05] + 0.25 * (qt_df.loc[0.95] - qt_df.loc[0.05]),
axis=0) / 2
t1 = timeit.default_timer()
onhour = df.groupby([pd.Grouper(freq='D')]).agg(count_something)
print(f"start_time in {timeit.default_timer() - t1}")
print(onhour.head())
如果您真的想加快计算速度,并且有办法并行化或分布您的计算,我想您可以使用python dask,但我认为它不会改善您的问题。