我一直在爲此工作一段時間,似乎無法解決這個問題。我有一個多索引的數據幀正與2級水平,這看起來如下:pandas在多索引數據幀內對連續事件進行計數
def data():
data = {'date': pd.Series(['2016-1-1', '2016-1-1', '2016-1-1',
'2016-1-2', '2016-1-2', '2016-1-2',
'2016-1-3', '2016-1-3', '2016-1-3',
'2016-1-4', '2016-1-4', '2016-1-4',
'2016-1-5', '2016-1-5', '2016-1-5']),
'group': pd.Series(['groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC']),
'series1': pd.Series([1, 2, 3,
1, 2, 3,
1, 2, 3,
1, 3, 4,
2, 3, 4]),
'series2': pd.Series([1, 3, 4,
2, 3, 3,
2, 4, 2,
1, 2, 3,
1, 2, 3])}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df.set_index(['date', 'group'], inplace=True)
return df
我有指定1 3的條件的欄。編寫這部分代碼可能有更簡潔的方式,但這不是我的問題。
def add_cond(df):
df['1minus2'] = df['series1'] - df['series2']
# first condition
mask1 = df['series1'] < df['series2']
df.loc[mask1, 'result'] = 'less'
# second condition
mask2 = df['series1'] > df['series2']
df.loc[mask2, 'result'] = 'greater'
# third condition
mask3 = df['series1'] == df['series2']
df.loc[mask3, 'result'] = 'equal'
return df
我的問題是,我想添加一個列來計算每日連續條件的數量。我已經嘗試了groupby
和cumcount
的幾種不同實現,我可以獲得所有條件的累積計數,但我希望在日期索引不連續時重置它們。
下面我列出了一些我已經嘗試過的相關文章。我認爲Pandas: conditional rolling count中的第二個答案可以工作,但它使用了一個transform
方法,因爲我有多個列,所以在這裏似乎不起作用。
按照Finding consecutive segments in a pandas data frame後面概述的策略,我創建了以下代碼,該代碼創建一個Series
,numpy arrays
,其中包含來自「結果」列的日期和組索引值以及數據。我想我可以用這樣一種方式來分割這個df,這樣我就可以計算每個連續的組,並將這些結果合併回原來的df。
df1 = df.reset_index(level=['date','group']).groupby(['result']).apply(np.array)
輸出將如下所示。
1
1
1
1
2
1
2
3
1
1
1
2
1
2
3
這是一個有點很難看到連續累計條件是否得到滿足與分層結構DF,但如果我拆散了DF它更容易看什麼我想要實現的。也許有一種方法可以使用unstack
來定位數據,這樣可以給我我想要的結果嗎?
df['result'].groupby(['date','group']).head().unstack()
Out[9]:
group groupA groupB groupC
date
2016-01-01 equal less less
2016-01-02 less less equal
2016-01-03 less less greater
2016-01-04 equal greater greater
2016-01-05 greater greater greater
我想你可以有很多關於你正在尋找的確切機制更加清晰。我不確定'date'列與它有什麼關係(是否相關)?另外,請注意''np.sign(series1 - series2)'是執行'add_cond()'的更好方法(如果這是您真實的情況)。 –
謝謝@約翰Zwinck我會看看我可以澄清。我在我的原始代碼中使用了np.sign,但不喜歡零作爲符號更改評估的結果,並且無法按照我希望的方式在lambda表達式中使用它。 – Greg