反復GROUPBY操作のパフォーマンスの向上:このデータフレームからは、基本的にはバイナリ行列であり、Iはマルチインデックスを有するデータフレームを有する
day day01 day02
session session1 session2 session3 session1 session2 session3
0 1 0 0 0 0 0
1 0 0 1 1 1 0
2 1 1 1 0 0 1
3 1 0 0 1 0 0
4 1 0 1 0 0 0
を、私は、行ごとに毎日の合計を計算する必要があります
day01 day02
0 1 0
1 1 2
2 3 1
3 1 1
4 2 0
そして、この合計で0、1の数...(値の数)を取得:
0 2
1 5
2 2
3 1
私はこのFを行う必要がありますがまたはセッションも可能です。各行のセッション合計:
session1 session2 session3
0 1 0 0
1 1 1 1
2 1 1 2
3 2 0 0
4 1 0 1
と値のカウントを取得する:ベースラインとして
0 5
1 8
2 2
、これはdf.groupby(level='day', axis=1).sum().stack().value_counts()
(及びdf.groupby(level='session', axis=1).sum().stack().value_counts()
)の結果です。シミュレーテッドアニーリングアルゴリズムの反復ごとにDataFrameが変更され、これらのカウントが再計算されます。コードをプロファイリングすると、groupby操作にかなりの時間を費やしていました。
私はgroupbyオブジェクトを保存し、各繰り返しでこれらのオブジェクトを合計しましたが、改善は約10%でした。私のコンピュータで
import numpy as np
import pandas as pd
prng = np.random.RandomState(0)
days = ['day{0:02d}'.format(i) for i in range(1, 11)]
sessions = ['session{}'.format(i) for i in range(1, 5)]
idx = pd.MultiIndex.from_product((days, sessions), names=['day', 'session'])
df = pd.DataFrame(prng.binomial(1, 0.25, (1250, 40)), columns=idx)
、次の2つの方法がそれぞれ3.8sと3.38sを取る:ここでは(私が持っているのと同様の)大きなデータフレームを作成するためのコードです。
def try1(df, num_repeats=1000):
for i in range(num_repeats):
session_counts = (df.groupby(level='session', axis=1, sort=False)
.sum()
.stack()
.value_counts(sort=False))
daily_counts = (df.groupby(level='day', axis=1, sort=False)
.sum()
.stack()
.value_counts(sort=False))
return session_counts, daily_counts
def try2(df, num_repeats=1000):
session_groups = df.groupby(level='session', axis=1, sort=False)
day_groups = df.groupby(level='day', axis=1, sort=False)
for i in range(num_repeats):
df.iat[0, 0] = (i + 1) % 2
session_counts = session_groups.sum().stack().value_counts(sort=False)
daily_counts = day_groups.sum().stack().value_counts(sort=False)
return session_counts, daily_counts
%time try1(df)
Wall time: 3.8 s
%time try2(df)
Wall time: 3.38 s
注:機能のループは、タイミングのためのものです。正しいタイミングを得るためには、DataFrameを修正する必要がありました。
私は現在、直接グループを再計算せずにカウントするデータフレームの変更を反映するために、別の方法に取り組んでいますが、私はまだ成功していません。影響を受けた行を追跡し、保存されたDataFramesを更新するのが遅いことが判明しました。
これらのgroupby操作のパフォーマンスを向上させる方法はありますか?あなたが唯一興味を持っている場合は
# Extract array
a,b = df.columns.levels
arr = df.values.reshape(-1,len(a),len(b))
# Get session counts
session_sums = arr.sum(1)
unq,count = np.unique(session_sums,return_counts=True)
session_counts_out = pd.Series(count,index=unq)
# Get daily count
daily_sums = arr.sum(2)
unq,count = np.unique(daily_sums,return_counts=True)
daily_counts_out = pd.Series(count,index=unq)
- 定期的なデータ形式(日、各行間のセッションの数と同じ数)を想定すると
トンにelemsの順番をい問題の出力は?さらに、2つの出力のインデックスは重要ですか? – Divakar
いいえ、そこに0、1などがいくつあるのか知っていれば、注文(またはその情報を保持するデータ構造)は重要ではありません。私は0に対応するものを知るべきであり、1は1に対応する。 – ayhan