簡體   English   中英

熊貓:如何按符號分組並按每n行取平均值

[英]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

編輯添加n天平均列

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM