私は30分ごとの日付グループ化を行っており、データセットの毎日の統計を計算するために適用していますが、時間がかかります。次の機能のパフォーマンスを向上させる方法はありますか?ベクトル化について読んだことがありますが、それを実装する方法がわかりません。
適用と変換を使用して希望の出力を取得しましたが、1年分のデータには約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())
あなたはすでにパンダのベクトル化最適化を使用しているので、多くの時間を得ることはできませんが、いくつかのトリックで1.5秒であなたを得ることができます。
1)aggを使用する
またはのagg
代わりにを使用すると、各列(電気とガス)に対して同じ計算が行われるため、より良い結果が得られます。transform
apply
2)分位数の計算を保存します。
5%分位数の3倍を計算しています。私はfunction
代わりにPythonを使用しましたが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を使用できると思いますが、問題をどれだけ改善できるかはわかりません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加