[英]Pandas - Rolling window - CustomIndex - right bound is not included in window for sum
我發現了 CustomIndexer,我可以看到“結束”(左邊界)不包含在我想要做的后續總和中。
這會導致2個問題:
總和未在我想要的行上實現
無法正確管理DataFrame的第一行(因為,該窗口不是帶有單個單元格的窗口,而是一個空窗口)
為了解決第一個后果,我采用了包含下一行以確保窗口在我希望它結束的地方結束。
但是,對於第二個問題,我沒有退路。
所以我在一個單獨的函數中測試了我的第一個自定義窗口以簡化調試。
import pandas as pd
import numpy as np
def custom_bounds(num_values, index, date_range):
start = np.empty(num_values, dtype=np.int64)
end = np.empty(num_values, dtype=np.int64)
ind_as_int = index.to_series().reset_index(drop=True)
dr_as_series = date_range.to_series()
# 1st item is skipped and default to 0
start[0]=0
end[0]=0
# Loop for other items
for i in range(num_values)[1:]:
previous_ts_in_dr = dr_as_series.loc[dr_as_series.index < ind_as_int.iat[i]].index[-1]
start[i] = ind_as_int.loc[ind_as_int >= previous_ts_in_dr].index[0]
end[i] = i-1
return start, end
我可以使用以下輸入值對其進行測試。
from random import seed
from random import randint
# DataFrame
ts_1h = pd.date_range(start='2020-01-01 00:00+00:00', end='2020-01-02 00:00+00:00', freq='1h')
seed(1)
values = [randint(0,10) for ts in ts_1h]
df = pd.DataFrame({'Values' : values}, index=ts_1h)
df.index.name='Timestamp'
# Processing
dr = pd.date_range(start='2019-12-31 23:00+00:00', end='2020-01-03 00:00+00:00', freq='3h')
運行它:
In [20]: df.head(4)
Out[20]:
Values
Timestamp
2020-01-01 00:00:00+00:00 2
2020-01-01 01:00:00+00:00 9
2020-01-01 02:00:00+00:00 1
2020-01-01 03:00:00+00:00 4
start, end = custom_bounds(num_values=df.shape[0], index=df.index, date_range=dr)
df_2 = pd.DataFrame({'int' : df.reset_index().index,
'start' : start,
'end' : end},
index = df.index)
df_2.loc[df_2.index.isin(dr), 'TS_3h'] = 'X'
所以基本上,在 df_2 中,我們可以看到標記自定義窗口開始和結束的整數。 這兩個邊界都必須包含在滾動窗口中。 我對您可以閱讀的值感到滿意。
In [22]: df_2.head(6)
Out[22]:
int start end TS_3h
Timestamp
2020-01-01 00:00:00+00:00 0 0 0 NaN
2020-01-01 01:00:00+00:00 1 0 0 NaN
2020-01-01 02:00:00+00:00 2 0 1 X
2020-01-01 03:00:00+00:00 3 2 2 NaN
2020-01-01 04:00:00+00:00 4 2 3 NaN
2020-01-01 05:00:00+00:00 5 2 4 X
所以我對下一步充滿信心。 我打算看到以下總和:
所以我將我的代碼集成到自定義的“get_window_bounds()”中,如下所示。
from pandas.api.indexers import BaseIndexer
class CustomIndexer(BaseIndexer):
def get_window_bounds(self, num_values, min_periods, center, closed):
start = np.empty(num_values, dtype=np.int64)
end = np.empty(num_values, dtype=np.int64)
ind_as_int = self.index.to_series().reset_index(drop=True)
dr_as_series = self.date_range.to_series()
# 1st item is skipped and default to 0
start[0]=0
end[0]=0
# Loop for other items
for i in range(num_values)[1:]:
previous_ts_in_dr = dr_as_series.loc[dr_as_series.index < ind_as_int.iat[i]].index[-1]
start[i] = ind_as_int.loc[ind_as_int >= previous_ts_in_dr].index[0]
end[i] = i-1
return start, end
indexer = CustomIndexer(index=df.index, date_range=dr, closed='both')
df['Sum'] = df.rolling(indexer).sum()
df.loc[df.index.isin(dr), 'TS_3h'] = 'X'
運行它:
In [25]: df.head(4)
Out[25]:
Values Sum TS_3h
Timestamp
2020-01-01 00:00:00+00:00 2 0.0 NaN
2020-01-01 01:00:00+00:00 9 0.0 NaN
2020-01-01 02:00:00+00:00 1 2.0 X
2020-01-01 03:00:00+00:00 4 0.0 NaN
如上所述,我打算看到以下結果:
所以問題是:我如何確保正確的界限包含在總和的計算中?
謝謝你的幫助。
好的,通過干預索引解決了。 抱歉打擾了。
def get_window_bounds(self, num_values, min_periods, center, closed):
start = np.empty(num_values, dtype=np.int64)
end = np.empty(num_values, dtype=np.int64)
ind_as_int = self.index.to_series().reset_index(drop=True)
dr_as_series = self.date_range.to_series()
# Loop over items
for i in range(num_values):
previous_ts_in_dr = dr_as_series.loc[dr_as_series.index < ind_as_int.iat[i]].index[-1]
start[i] = ind_as_int.loc[ind_as_int >= previous_ts_in_dr].index[0]
end[i] = i
# Correct end[0]
end[0]=1
return start, end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.