Pandas Dataframe および Series での roller().apply() の使用

Mehvish Ashiq 2023年6月21日
  1. Pandas DataFrame で rolling().apply() を使用する
  2. ラムダでrolling.apply
  3. Pandas シリーズで rolling().apply() を使用する
Pandas Dataframe および Series での roller().apply() の使用

Pandas ライブラリには多くの便利な関数があり、指定されたデータセットに対して複雑な計算を実行できる rolling() はその 1つです。 apply() と呼ばれるメソッドもあり、特定の関数/メソッドをローリング ウィンドウで完全なデータに適用します。

rolling().apply() を Python シリーズとデータ フレームで使用できます。 このチュートリアルでは、rolling() および apply() メソッドについて説明し、Pandas データフレームとシリーズで rolling().apply() を使用する方法も示します。

Pandas DataFrame で rolling().apply() を使用する

データフレームで rolling().apply() を使用する方法を段階的に学びましょう。

  • ライブラリをインポートします。
    import pandas as pd
    import numpy as np
    

    まず、必要なライブラリ、データ フレームを操作するための pandasnumpy.median() 関数を使用して配列を操作するための numpy をインポートします。

  • データフレームを作成します。
    points_df = pd.DataFrame(
        {
            "Team_A": [12, 23, 34, 45, 32, 45, 32, 21, 33],
            "Team_B": [13, 24, 35, 46, 33, 46, 33, 22, 34],
            "Team_C": [14, 25, 36, 47, 34, 47, 34, 23, 35],
            "Team_D": [15, 26, 37, 48, 35, 48, 35, 24, 36],
        }
    )
    print(points_df)
    

    出力:

     Team_A Team_B Team_C Team_D
    0      12      13      14      15
    1      23      24      25      26
    2      34      35      36      37
    3      45      46      47      48
    4      32      33      34      35
    5      45      46      47      48
    6      32      33      34      35
    7      21      22      23      24
    8      33      34      35      36
    

    次に、Team_ATeam_BTeam_C、および Team_D の異なるポイントを含む points_df という名前のデータフレームを作成します。 デフォルトのインデックスにはヘッダー (見出し) がないことがわかります。

    次のステップで、その見出しを作成しましょう。

  • デフォルトの列インデックスの見出しを index として設定します。
    points_df.index.names = ["index"]
    print(points_df)
    

    出力:

    	 Team_A Team_B Team_C Team_D
    index
    0          12      13      14      15
    1          23      24      25      26
    2          34      35      36      37
    3          45      46      47      48
    4          32      33      34      35
    5          45      46      47      48
    6          32      33      34      35
    7          21      22      23      24
    8          33      34      35      36
    

    ご覧のとおり、見出し indexTeam_ATeam_BTeam_C、および Team_D と一致していません。 次のステップでそれを行いましょう。

  • points_df データフレームのすべての見出しを揃えます。
    points_df.columns.name = points_df.index.name
    points_df.index.name = None
    print(points_df)
    

    出力:

    index Team_A Team_B Team_C Team_D
    0          12      13      14      15
    1          23      24      25      26
    2          34      35      36      37
    3          45      46      47      48
    4          32      33      34      35
    5          45      46      47      48
    6          32      33      34      35
    7          21      22      23      24
    8          33      34      35      36
    
  • calculate_median() 関数を作成します。
    def calculate_median(n):
        return np.median(n)
    

    この関数は系列 (数値の配列と言えます) を取り、その系列の中央値を返します。

  • points_df データフレームで rolling().apply() を使用します。
    points_df = points_df.rolling(2).apply(calculate_median)
    print(points_df)
    

    出力:

    index Team_A Team_B Team_C Team_D
    0         NaN     NaN     NaN     NaN
    1        17.5    18.5    19.5    20.5
    2        28.5    29.5    30.5    31.5
    3        39.5    40.5    41.5    42.5
    4        38.5    39.5    40.5    41.5
    5        38.5    39.5    40.5    41.5
    6        38.5    39.5    40.5    41.5
    7        26.5    27.5    28.5    29.5
    8        27.0    28.0    29.0    30.0
    

    ここでは、rolling() を使用して、ローリング ウィンドウの計算を行います。 このアイデア (ローリング ウィンドウ) は、信号プロセスと時系列データセットで使用されます。

    rolling()、その構文、ローリング ウィンドウ機能、およびさまざまなローリング関数のデモンストレーションによるその作業プロセスに関する記事を既に書いています。 こちらで読めます。

    apply() 関数を使用して、指定されたデータにカスタム関数 (この場合は calculate_median()) を適用します。

  • これが完全なソースコードです。
    import pandas as pd
    import numpy as np
    
    points_df = pd.DataFrame(
        {
            "Team_A": [12, 23, 34, 45, 32, 45, 32, 21, 33],
            "Team_B": [13, 24, 35, 46, 33, 46, 33, 22, 34],
            "Team_C": [14, 25, 36, 47, 34, 47, 34, 23, 35],
            "Team_D": [15, 26, 37, 48, 35, 48, 35, 24, 36],
        }
    )
    
    points_df.index.names = ["index"]
    points_df.columns.name = points_df.index.name
    points_df.index.name = None
    
    print("Before rolling().apply():\n\n")
    print(points_df)
    
    
    def calculate_median(n):
        return np.median(n)
    
    
    points_df = points_df.rolling(2).apply(calculate_median)
    print("\n\nBefore rolling().apply():\n\n")
    print(points_df)
    

    出力:

    Before rolling().apply():
    
    
    index Team_A Team_B Team_C Team_D
    0          12      13      14      15
    1          23      24      25      26
    2          34      35      36      37
    3          45      46      47      48
    4          32      33      34      35
    5          45      46      47      48
    6          32      33      34      35
    7          21      22      23      24
    8          33      34      35      36
    
    
    Before rolling().apply():
    
    
    index Team_A Team_B Team_C Team_D
    0         NaN     NaN     NaN     NaN
    1        17.5    18.5    19.5    20.5
    2        28.5    29.5    30.5    31.5
    3        39.5    40.5    41.5    42.5
    4        38.5    39.5    40.5    41.5
    5        38.5    39.5    40.5    41.5
    6        38.5    39.5    40.5    41.5
    7        26.5    27.5    28.5    29.5
    8        27.0    28.0    29.0    30.0
    

ラムダでrolling.apply

次のコードを検討してください。

from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np


def test(df):
    return np.mean(df)


sc = StandardScaler()

tmp = pd.DataFrame(
    np.random.randn(2000, 2) / 10000,
    index=pd.date_range("2001-01-01", periods=2000),
    columns=["A", "B"],
)

print("Test 1: ")
print(tmp.rolling(window=5, center=False).apply(lambda x: test(x)))

print("SC_Fit: ")
print(
    tmp.rolling(window=5, center=False).apply(
        lambda x: (x[-1] - x.mean()) / x.std(ddof=1)
    )
)

出力:

Test 1:
                   A         B
2001-01-01       NaN       NaN
2001-01-02       NaN       NaN
2001-01-03       NaN       NaN
2001-01-04       NaN       NaN
2001-01-05 -0.000039  0.000053
...              ...       ...
2006-06-19  0.000022 -0.000021
2006-06-20  0.000005 -0.000027
2006-06-21  0.000024 -0.000060
2006-06-22  0.000023 -0.000038
2006-06-23  0.000014 -0.000017
[2000 rows x 2 columns]

SC_Fit:

                   A         B
2001-01-01       NaN       NaN
2001-01-02       NaN       NaN
2001-01-03       NaN       NaN
2001-01-04       NaN       NaN
2001-01-05 -0.201991  0.349646
...              ...       ...
2006-06-19  1.035835 -0.688231
2006-06-20 -0.595888  1.057016
2006-06-21 -0.640150 -1.399535
2006-06-22 -0.535689  1.244345
2006-06-23  0.510958  0.614429

[2000 rows x 2 columns]

lambda 関数の x は (ローリング) series/ndarray を表すため、関数は次のように記述できます (x[-1] は現在のローリング データ ポイントを参照します)。

lambda x: (x[-1] - x.mean()) / x.std(ddof=1)

Pandas シリーズで rolling().apply() を使用する

同様に、Pandas シリーズに rolling().apply() を使用できます。 次のコード フェンスは、1つの違いを除いて Pandas データ フレーム用に記述したものと同じです。ここではシリーズを使用しています。

完全なソース コードを以下に示しますが、シリーズの詳細については こちら を参照してください。

コード例:

import pandas as pd
import numpy as np

points_series = pd.Series(
    [12, 23, 34, 45], index=["Team_A", "Team_B", "Team_C", "Team_D"]
)


print("Before rolling().apply():\n\n")
print(points_series)


def calculate_median(n):
    return np.median(n)


points_series = points_series.rolling(2).apply(calculate_median)
print("\n\nBefore rolling().apply():\n\n")
print(points_series)

出力:

Before rolling().apply():


Team_A    12
Team_B    23
Team_C    34
Team_D    45
dtype: int64


Before rolling().apply():


Team_A     NaN
Team_B    17.5
Team_C    28.5
Team_D    39.5
dtype: float64
著者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook