[英]Pandas: how to group-by a symbol and take the mean every n rows
假設我有以下數據框df :
date symbol_a symbol_b ratio
0 2017/01/01 AAAA AA 10
1 2017/01/02 AAAA AA 20
2 2017/01/03 AAAA AA 30
3 2017/01/04 AAAA AA 10
4 2017/01/05 AAAA AA 10
5 2017/01/06 AAAA AA 10
6 2017/01/01 BBBB BB 10
7 2017/01/02 BBBB BB 20
8 2017/01/03 BBBB BB 30
9 2017/01/04 BBBB BB 10
10 2017/01/01 CCCC CC 10
11 2017/01/02 CCCC CC 20
12 2017/01/03 CCCC CC 30
13 2017/01/04 CCCC CC 10
14 2017/01/05 CCCC CC 10
15 2017/01/06 CCCC CC 5
我對比率列的平均值感興趣(這來自之前的數據框,其中有兩個附加列value_a value_b和ratio = value_a / value_b,或多或少)。 我想做的是以下內容:
每n個元素用symbol_a(或_b實際上是相同的)取平均值。 假設n = 3。
通常我會這樣做:
df.groupby(['symbol_a','symbol_b']).mean()
但是,我希望每3天獲得一次子裝置(實際時間跨度顯然要長得多,而且每5天需要一次)。
最初我以為我總是會有相同數量的符號,可以被n整除,所以我嘗試了類似的東西:
df.groupby([df.index/n, 'symbol_a', 'symbol_b']).mean().reset_index()
這非常有效,但強烈依賴於n的可分性假設。 不幸的是,不僅這是我想要放棄的假設,而且我還注意到並非所有符號都出現了n次:例如,注意symbol_a“BBBB”僅出現四次(天)。 這當然使得上述嘗試完全不可靠,因為它將混合不同符號的比率值。
回顧一下,我需要一些東西讓我每n個元素都有一個比率列的平均值,如果符號的數量不能被n整除,它會得到每n個的平均值,最后得到提醒的平均值(如果number_of_symbols <n只是這個數字的平均值)。
例如,結果看起來像(假設n = 3):
symbol_a symbol_b 3_mean_ratio
0 AAAA AA 20
1 AAAA AA 10
2 BBBB BB 20
4 BBBB BB 10
5 CCCC CC 20
6 CCCC CC 8.33
有沒有辦法做這樣的事情? 非常感謝任何幫助,謝謝。
編輯:感謝您的答案到目前為止。 最后一件理想的事情是將新的n-days-ratio列放在原始列旁邊的簡單方法。 當然這個新的長度更短但我不介意重復這些元素。 基本上我需要一種方法來根據這個平均值選擇“好行”。 到目前為止,我正在創建一個字典作為中間步驟,但我確信有更好的方法。 如果我能獲得類似下面的東西會很棒:
date symbol_a symbol_b ratio n-days-ratio
0 2017/01/01 AAAA AA 10 20
1 2017/01/02 AAAA AA 20 20
2 2017/01/03 AAAA AA 30 20
3 2017/01/04 AAAA AA 10 10
4 2017/01/05 AAAA AA 10 10
5 2017/01/06 AAAA AA 10 10
6 2017/01/01 BBBB BB 10 20
7 2017/01/02 BBBB BB 20 20
8 2017/01/03 BBBB BB 30 20
9 2017/01/04 BBBB BB 10 10
10 2017/01/01 CCCC CC 10 20
11 2017/01/02 CCCC CC 20 20
12 2017/01/03 CCCC CC 30 20
13 2017/01/04 CCCC CC 10 8.3
14 2017/01/05 CCCC CC 10 8.3
15 2017/01/06 CCCC CC 5 8.3
g = df.groupby('symbol_a').cumcount()
df['n-days-ratio'] = df.groupby(['symbol_a','symbol_b',g // 3]).transform(lambda x: x.mean())
df
輸出:
date symbol_a symbol_b ratio n-days-ratio
0 2017/01/01 AAAA AA 10 20.000000
1 2017/01/02 AAAA AA 20 20.000000
2 2017/01/03 AAAA AA 30 20.000000
3 2017/01/04 AAAA AA 10 10.000000
4 2017/01/05 AAAA AA 10 10.000000
5 2017/01/06 AAAA AA 10 10.000000
6 2017/01/01 BBBB BB 10 20.000000
7 2017/01/02 BBBB BB 20 20.000000
8 2017/01/03 BBBB BB 30 20.000000
9 2017/01/04 BBBB BB 10 10.000000
10 2017/01/01 CCCC CC 10 20.000000
11 2017/01/02 CCCC CC 20 20.000000
12 2017/01/03 CCCC CC 30 20.000000
13 2017/01/04 CCCC CC 10 8.333333
14 2017/01/05 CCCC CC 10 8.333333
15 2017/01/06 CCCC CC 5 8.333333
我們來使用:
g = df.groupby('symbol_a')['ratio']。transform(lambda x:x.astype(bool).cumsum()。add(-1))
讓我們使用piRSquare的cumcount
方法。
g = df.groupby('symbol_a').cumcount()
df_out = df.groupby(['symbol_a','symbol_b',g // 3]).mean().reset_index(level=2, drop=True).reset_index()
輸出:
symbol_a symbol_b ratio
0 AAAA AA 20.000000
1 AAAA AA 10.000000
2 BBBB BB 20.000000
3 BBBB BB 10.000000
4 CCCC CC 20.000000
5 CCCC CC 8.333333
使用cumcount() // 3
生成一個新列以進行分組
cols = ['symbol_a', 'symbol_b']
cc = df.groupby(cols).cumcount() // 3
cols += ['Cumcount']
d1 = df.assign(Cumcount=cc)
d1.groupby(cols).ratio.mean().reset_index('Cumcount', drop=True).reset_index()
symbol_a symbol_b ratio
0 AAAA AA 20.000000
1 AAAA AA 10.000000
2 BBBB BB 20.000000
3 BBBB BB 10.000000
4 CCCC CC 20.000000
5 CCCC CC 8.333333
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.