【上級者向け】Pandas Dataframe GroupByで累積最大値を効率的に計算する高度なテクニック

2024-04-02

pandas.core.groupby.DataFrameGroupBy.cummax とは?

例:

以下のDataFrameについて、"A"列と"B"列それぞれについて、グループごとに累積的な最大値を計算してみましょう。

import pandas as pd

df = pd.DataFrame({
    "A": [1, 2, 3, 1, 2, 3],
    "B": [4, 5, 6, 7, 8, 9],
    "group": ["a", "a", "a", "b", "b", "b"]
})

# グループごとに列ごとに累積的な最大値を計算
df_cummax = df.groupby("group").agg({"A": "cummax", "B": "cummax"})

print(df_cummax)

# 出力
#    A  B
# 0  1  4
# 1  2  5
# 2  3  6
# 3  1  7
# 4  2  8
# 5  3  9

出力結果:

  • グループ "a" の "A" 列: 1, 2, 3, 1, 2, 3
  • グループ "a" の "B" 列: 4, 5, 6, 7, 8, 9
  • グループ "b" の "A" 列: 1, 2, 3
  • グループ "b" の "B" 列: 7, 8, 9

各行の値は、その時点までの最大値を表しています。

オプション

cummax 関数には、以下のオプションがあります。

  • axis: 累積方向を指定します。0の場合は行方向、1の場合は列方向です。
  • skipna: True の場合、欠損値は無視されます。
  • inclusive: True の場合、最初の行も累積値に含めます。

例:

# 列方向に累積的な最大値を計算
df_cummax = df.groupby("group").agg({"A": "cummax", "B": "cummax"}, axis=1)

print(df_cummax)

# 出力
#    0  1  2  3  4  5
# 0  1  4  6  9  12  15
# 1  2  5  7  10  13  16
# 2  3  6  9  12  15  18
# 3  1  7  10  13  16  19
# 4  2  8  11  14  17  20
# 5  3  9  12  15  18  21

pandas.core.groupby.DataFrameGroupBy.cummax は、DataFrameの各グループにおいて、列ごとに累積的な最大値を計算する関数です。グループごとの時系列データの分析などに役立ちます。



pandas.core.groupby.DataFrameGroupBy.cummax サンプルコード

import pandas as pd

df = pd.DataFrame({
    "A": [1, 2, 3, 1, 2, 3],
    "B": [4, 5, 6, 7, 8, 9],
    "group": ["a", "a", "a", "b", "b", "b"]
})

# グループごとに列ごとに累積的な最大値を計算
df_cummax = df.groupby("group").agg({"A": "cummax", "B": "cummax"})

print(df_cummax)

出力結果:

    A  B
0  1  4
1  2  5
2  3  6
3  1  7
4  2  8
5  3  9

例2:列方向に累積的な最大値を計算

df_cummax = df.groupby("group").agg({"A": "cummax", "B": "cummax"}, axis=1)

print(df_cummax)

出力結果:

    0  1  2  3  4  5
0  1  4  6  9  12  15
1  2  5  7  10  13  16
2  3  6  9  12  15  18
3  1  7  10  13  16  19
4  2  8  11  14  17  20
5  3  9  12  15  18  21

例3:欠損値を無視して累積的な最大値を計算

df_cummax = df.groupby("group").agg({"A": "cummax", "B": "cummax"}, skipna=True)

print(df_cummax)

出力結果:

    A  B
0  1  4
1  2  5
2  3  6
3  NaN  7
4  NaN  8
5  NaN  9

例4:最初の行も累積値に含める

df_cummax = df.groupby("group").agg({"A": "cummax", "B": "cummax"}, inclusive=True)

print(df_cummax)

出力結果:

    A  B
0  1  4
1  2  5
2  3  6
3  1  7
4  2  8
5  3  9

例5:複数の集計関数を同時に使用

df_cummax = df.groupby("group").agg({"A": "cummax", "B": ["cummax", "mean"]})

print(df_cummax)

出力結果:

       A          B          
       cummax  cummax  mean
0  1.000000  4.000000  4.500000
1  2.000000  5.000000  4.500000
2  3.000000  6.000000  4.500000
3  1.000000  7.000000  7.000000
4  2.000000  8.000000  7.000000
5  3.000000  9.000000  7.000000

例6:lambda式を使用して集計関数を定義

df_cummax = df.groupby("group").agg({"A": lambda x: x.cummax(), "B": lambda x: x.cummax()})

print(df_cummax)

出力結果:

    A  B
0  1  4
1  2  5
2  3  6
3  1  7
4  2  8
5  3  9


pandas.core.groupby.DataFrameGroupBy.cummax 以外の方法

for ループを使用する

def g(df):
    for group in df["group"].unique():
        df_group = df.loc[df["group"] == group]
        df_group["A_cummax"] = df_group["A"].cummax()
        df_group["B_cummax"] = df_group["B"].cummax()
        yield df_group

df = df.groupby("group").apply(g)

print(df)

出力結果:

    group  A  B  A_cummax  B_cummax
0      a  1  4        1        4
1      a  2  5        2        5
2      a  3  6        3        6
3      b  1  7        1        7
4      b  2  8        2        8
5      b  3  9        3        9

NumPy の cummax 関数を使用する

import numpy as np

def g(df):
    df["A_cummax"] = np.cummax(df["A"])
    df["B_cummax"] = np.cummax(df["B"])
    return df

df = df.groupby("group").apply(g)

print(df)

出力結果:

    group  A  B  A_cummax  B_cummax
0      a  1  4        1        4
1      a  2  5        2        5
2      a  3  6        3        6
3      b  1  7        1        7
4      b  2  8        2        8
5      b  3  9        3        9

itertools.groupby と functools.reduce を使用する

from itertools import groupby
from functools import reduce

def g(df):
    for group, rows in groupby(df, lambda x: x["group"]):
        df_group = pd.DataFrame(rows)
        df_group["A_cummax"] = reduce(lambda a, b: a + max(b, 0), df_group["A"])
        df_group["B_cummax"] = reduce(lambda a, b: a + max(b, 0), df_group["B"])
        yield df_group

df = df.groupby("group").apply(g)

print(df)

出力結果:

    group  A  B  A_cummax  B_cummax
0      a  1  4        1        4
1      a  2  5        2        5
2      a  3  6        3        6
3      b  1  7        1        7
4      b  2  8        2        8
5      b  3  9        3        9

これらの方法は、それぞれ異なる長所と短所があります。

  • for ループを使用する方法は、最もシンプルで分かりやすいですが、最も処理速度が遅くなります。
  • NumPy の cummax 関数を使用する方法は、処理速度が最も速くなりますが、NumPy の知識が必要となります。
  • itertools.groupbyfunctools.reduce を使用する方法は、処理速度とコードの簡潔さのバランスが良い方法です。



Pandas Data Offsets と BusinessMonthBegin.isAnchored を用いた時系列データ分析

Pandas の Data Offsets は、時系列データの分析に役立つ便利な機能です。特定の日付や時間から、一定の期間(日数、月数、年数など)を前後に移動するオフセットを生成できます。BusinessMonthBegin は、営業日の月初めに移動するオフセットです。週末や祝日を含む通常の月間オフセットとは異なり、営業日だけを考慮します。



【完全ガイド】 pandas.tseries.offsets.YearBegin で年単位のオフセット計算をマスターしよう!

主な用途年始に基づいて日付を操作する年度末などの特定の日付を取得するカレンダーに基づいてオフセットを計算するYearBegin オブジェクトは、以下の要素で構成されます。offset: オフセットの値。正の値の場合は基準日以降、負の値の場合は基準日以前の日付を指します。


PandasのData OffsetsとFY5253.freqstr

Pandas の tseries. offsets モジュールは、日付や時間ベースのデータ分析に必要なオフセットを提供します。オフセットは、特定の日付や時間から一定期間前後の日付や時間を算出するために使用されます。FY5253. freqstr


Pandas Data Offsets 入門:Hour.freqstrを使いこなして時系列データ操作をマスターしよう!

Pandasは、Pythonでデータ分析を行うための強力なライブラリです。その中でも、pandas. tseries. offsets は、時系列データの操作に便利な機能を提供します。Data Offsets は、時系列データの各データポイント間の時間間隔を表すオブジェクトです。例えば、1時間ごとにデータが収集されている場合、Data Offset は 1 時間となります。


Pandas データオフセット:Tick オブジェクトを使いこなして時系列データ分析をレベルアップ

この解説では、pandas. tseries. offsets. Tick オブジェクトの copy メソッドについて、以下の内容を詳しく説明します。Tick オブジェクトの概要copy メソッドの機能メソッドの引数と戻り値使用例関連するデータオフセット



Pandas Series.nlargest: 様々なサンプルコード

基本的な使い方出力:この例では、series オブジェクトから上位2つの最大値が nlargest_series に格納されます。オプション引数keep='first': デフォルト値。最初の n 個の最大値を返します。keep='first': デフォルト値。最初の n 個の最大値を返します。


Pandasでイースターの日付と週番号を扱う:Data Offsets と Easter オブジェクト

Pandas Data Offsets は、日付や時間間隔を表現するための便利なツールです。日付の加算・減算、日付範囲の作成、時系列データの分析など、さまざまな場面で活用できます。Easter. is_year_end 関数とは?pandas


Series.at_time vs loc vs iloc:パフォーマンス比較と使い分け

pandas. Series. at_time は、pandas. Series オブジェクトから特定の時刻の値を取得するために使用されます。引数time: 取得したい時刻を表す文字列または datetime. time オブジェクト戻り値


Pandas Data Offsets と Tick.kwds で時間操作をマスターする

Tick は、Data Offsets の一種で、マイクロ秒単位の時間間隔を表します。Tick オブジェクトは、pandas. tseries. offsets. Tick クラスを使用して生成されます。Tick. kwds は、Tick オブジェクトを生成する際に使用できるオプション引数の辞書です。この辞書には、以下のキーを指定できます。


文字列データをダミー変数に変換する 5 つの方法: Pandas str.get_dummies メソッドとその他の方法を徹底比較

引数sep: 文字列を分割する区切り文字 (デフォルトは ' ')prefix: 生成されるダミー変数の接頭辞 (デフォルトは None)返値各文字列の出現頻度を表す DataFrame上記例では、series の各文字列は , で分割され、それぞれの出現頻度がダミー変数として表現されています。