DataFrameでグループ間の差と平均を計算(グループへの集約関数の適用)

Calculate difference and mean over groups in DataFrame – StackOverflow

timestamp列がソート済みであると仮定できそうなので,各グループの最後と最初の差を求めるのがリーズナブルチョイス.

import io
import pandas as pd


strings = """ID1    ID2     timestamp   x    y
0      0       43          1    40
0      0       53          20   41
0      0       63          21   41
0      1       73          5    100
0      1       75          6    99
0      1       83          7    87
1      0       100         34   23
1      0       200         0    0
1      0       210         0    22
1      0       222         22   15
2      0       300         22   15
2      1       450         22   15
2      1       451         22   15"""

df = (
    pd.read_csv(io.StringIO(strings), sep='\s+')
    .groupby(['ID1', 'ID2'], as_index=False)
    .agg({
        'timestamp': lambda x: x.iat[-1] - x.iat[0],
        'x': 'mean',
        'y': 'mean'
    })
)
df
ID1 ID2 timestamp   x   y
0   0   0   20  14  40.666667
1   0   1   10  6   95.333333
2   1   0   122 14  15.000000
3   2   0   0   22  15.000000
4   2   1   1   22  15.000000

回答でnumpy.ptpを用いているが,この書き方だと(関連の様に以前は問題なかったが,どのバージョンからか分からないが)ワーニングが出るし,効率的ではない.numpy.ptpを用いる場合は,シリーズではなくnumpy.ndarrayを渡すべき.

df = pd.read_csv(io.StringIO(strings), sep='\s+')
df2 = pd.concat([df]*100000, ignore_index=True)
%timeit df2.groupby(['ID1', 'ID2'], as_index=False).agg({'timestamp': lambda x: x.iat[-1] - x.iat[0], 'x': 'mean', 'y': 'mean'})
%timeit df2.groupby(['ID1', 'ID2'], as_index=False).agg({'timestamp': lambda x: x.max() - x.min(), 'x': 'mean', 'y': 'mean'})
%timeit df2.groupby(['ID1', 'ID2'], as_index=False).agg({'timestamp': np.ptp, 'x': 'mean', 'y': 'mean'})
%timeit df2.groupby(['ID1', 'ID2'], as_index=False).agg({'timestamp': lambda x: np.ptp(x.to_numpy()), 'x': 'mean', 'y': 'mean'})
10 loops, best of 3: 163 ms per loop
10 loops, best of 3: 185 ms per loop
/usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py:2389: FutureWarning: Method .ptp is deprecated and will be removed in a future version. Use numpy.ptp instead.
  return ptp(axis=axis, out=out, **kwargs)
10 loops, best of 3: 183 ms per loop
10 loops, best of 3: 167 ms per loop

 
 
関連:
pandas.DataFrame.applyは(時空間効率の観点からは)使用するべきではない – 使用すべき明確な理由がない限りpandas.DataFrame.applyはリーズナブルチョイスになり得ない

数値,文字列を含むデータフレームから数値列のみを選択

広告
カテゴリー: 未分類 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください