私は、pandas.rolling_apply
データを分布に当てはめて値を取得するために使用していますが、ローリング適合度 (具体的には p 値) も報告する必要があります。現在は次のようにしています。
def func(sample):
fit = genextreme.fit(sample)
return genextreme.isf(0.9, *fit)
def p_value(sample):
fit = genextreme.fit(sample)
return kstest(sample, 'genextreme', fit)[1]
values = pd.rolling_apply(data, 30, func)
p_values = pd.rolling_apply(data, 30, p_value)
results = pd.DataFrame({'values': values, 'p_value': p_values})
問題は、大量のデータがあり、フィット関数が高価なので、サンプルごとに 2 回呼び出したくないということです。代わりに、次の操作を行います。
def func(sample):
fit = genextreme.fit(sample)
value = genextreme.isf(0.9, *fit)
p_value = kstest(sample, 'genextreme', fit)[1]
return {'value': value, 'p_value': p_value}
results = pd.rolling_apply(data, 30, func)
結果はDataFrame
2 つの列を持つ です。これを実行しようとすると、例外が発生します: TypeError: a float is required
。これを実現することは可能ですか? 可能であれば、どのようにすればよいですか?
ベストアンサー1
私も同様の問題を抱えていましたが、適用中に別のヘルパー クラスのメンバー関数を使用して解決しました。そのメンバー関数は、必要に応じて単一の値を返しますが、他の計算結果をクラスのメンバーとして保存し、後で使用することができます。
簡単な例:
class CountCalls:
def __init__(self):
self.counter = 0
def your_function(self, window):
retval = f(window)
self.counter = self.counter + 1
TestCounter = CountCalls()
pandas.Series.rolling(your_seriesOrDataframeColumn, window = your_window_size).apply(TestCounter.your_function)
print TestCounter.counter
関数 f が 2 つの値 v1、v2 のタプルを返すと仮定します。次に、v1 を返して、それをデータフレームの column_v1 に割り当てることができます。2 番目の値 v2 は、ヘルパー クラス内のシリーズ series_val2 に蓄積するだけです。その後、そのシリーズをデータフレームの新しい列として割り当てるだけです。JML