実際にボトルネックがgroupby
です。この特定の問題に実際にgroupby
を使用する必要はありません。 sort
にデータフレームGROUP
を入力するには、ソートされたデータフレームでdiff
を実行し、MASK
によってfilter
を実行してください。私たちは、あなたがこの
を使用することができ、(最初の要素は差分演算のために無意味であるため)MASKは、常に各グループの最初の要素のために偽であると想定し、前とソート後にグループ内で変わらず
を順序を維持するためにkind='mergesort'
を使用する必要があります。
pd.concat([df.VALUE, df.sort_values(by="GROUP", kind='mergesort').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]
性能試験:
MAXN = 200000
GROUPS = 10000
df = pd.DataFrame({"GROUP": np.ceil(np.random.rand(MAXN)*GROUPS), "VALUE": np.ceil(np.random.rand(MAXN)*10000), "MASK":np.floor(np.random.rand(MAXN)*2).astype("bool")})
%timeit t1 = pd.concat([df.VALUE, df.groupby('GROUP').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]
# 1 loop, best of 3: 1.28 s per loop
%timeit t2 = pd.concat([df.VALUE, df.sort_values(by="GROUP", kind='mergesort').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]
#10 loops, best of 3: 63.1 ms per loop
#MAXN = 2000000
#GROUPS = 1000000
%timeit t2 = pd.concat([df.VALUE, df.sort_values(by="GROUP", kind='mergesort').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]
#1 loop, best of 3: 1.24 s per loop
以下のスピードのコメントに反応して:グループの数が多いGROUPBYの速さで大きな改善があったとして、あなたはパンダの新しいバージョンを使用していることを確認してください。それとは別に、同じサブセットで繰り返し計算を行う場合は、データのサブセット化について考えるかもしれません。 – JohnE