日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Pandas必備技能之“分組聚合操作”

 立志德美 2019-07-08

TUSHARE  金融與技術(shù)學(xué)習(xí)興趣小組 

翻譯整理 | 一只小綠怪獸

在處理數(shù)據(jù)的過程中,知道如何對數(shù)據(jù)集進(jìn)行分組、聚合操作是一項必備的技能,能夠大大提升數(shù)據(jù)分析的效率。

分組是指根據(jù)一個或多個鍵將數(shù)據(jù)拆分為多個組的過程,這里的鍵可以理解為分組的條件。聚合指的是任何能夠從數(shù)組產(chǎn)生標(biāo)量值的數(shù)據(jù)轉(zhuǎn)換過程。分組、聚合操作一般會同時出現(xiàn),用于計算分組數(shù)據(jù)的統(tǒng)計值或?qū)崿F(xiàn)其他功能。

本文會介紹如何利用Pandas中提供的groupby功能,靈活高效地對數(shù)據(jù)集進(jìn)行分組、聚合操作。

【工具】Python 3

【數(shù)據(jù)】Tushare

【注】示例注重的是方法的講解,請大家靈活掌握。

01

原理

Pandas中用groupby機制進(jìn)行分組、聚合操作的原理可以分為三個階段,即“拆分split-應(yīng)用apply-合并combine”,下圖就是一個簡單的分組聚合過程。

第一階段,數(shù)據(jù)會根據(jù)一個或多個鍵key被拆分split成多組,然后將一個函數(shù)應(yīng)用apply到各個分組并產(chǎn)生一個新值,最后所有這些函數(shù)的執(zhí)行結(jié)果會被合并combine到最終的結(jié)果對象中。

02

groupby函數(shù)

用Pandas中提供的分組函數(shù)groupby【1】能夠很方便地對表格進(jìn)行分組操作。我們先從tushare.pro上面獲取一個包含三只股票日線行情數(shù)據(jù)的表格。

import tushare as ts
import pandas as pd


pd.set_option('expand_frame_repr'False)  # 顯示所有列
ts.set_token('your token')
pro = ts.pro_api()

code_list = ['000001.SZ''600000.SH''000002.SZ']
stock_data = pd.DataFrame()
for code in code_list:
    print(code)
    df = pro.daily(ts_code=code, start_date='20180101', end_date='20180104')
    stock_data = stock_data.append(df, ignore_index=True)

print(stock_data)


000001.SZ
600000.SH
000002.SZ
     ts_code trade_date   open   high    low  close  pre_close  change  pct_chg         vol       amount
0  000001.SZ   20180104  13.32  13.37  13.13  13.25      13.33   -0.08    -0.60  1854509.48  2454543.516
1  000001.SZ   20180103  13.73  13.86  13.20  13.33      13.70   -0.37    -2.70  2962498.38  4006220.766
2  000001.SZ   20180102  13.35  13.93  13.32  13.70      13.30    0.40     3.01  2081592.55  2856543.822
3  600000.SH   20180104  12.70  12.73  12.62  12.66      12.66    0.00     0.00   278838.04   353205.838
4  600000.SH   20180103  12.73  12.80  12.66  12.66      12.72   -0.06    -0.47   378391.01   480954.809
5  600000.SH   20180102  12.61  12.77  12.60  12.72      12.59    0.13     1.03   313230.53   398614.966
6  000002.SZ   20180104  32.76  33.53  32.10  33.12      32.33    0.79     2.44   529085.80  1740602.533
7  000002.SZ   20180103  32.50  33.78  32.23  32.33      32.56   -0.23    -0.71   646870.20  2130249.691
8  000002.SZ   20180102  31.45  32.99  31.45  32.56      31.06    1.50     4.83   683433.50  2218502.766

接下來,我們以股票代碼'ts_code'這一列為鍵,用groupby函數(shù)對表格進(jìn)行分組,代碼如下。

grouped = stock_data.groupby('ts_code')
print(grouped)

<pandas.core.groupby.groupby.DataFrameGroupBy object at 0x000002B1AD25D4A8>

注意,這里并沒有打印出表格,而是一個GroupBy對象,因為我們還沒有對分組進(jìn)行計算。也就是說,目前只完成了上面提到的第一個階段的拆分split操作,需要繼續(xù)調(diào)用聚合函數(shù)完成計算。

03

聚合函數(shù)

常用的聚合函數(shù)如下,我們繼續(xù)用上面的表格數(shù)據(jù)進(jìn)行演示。

① 按列'ts_code'分組,用函數(shù).mean()計算分組中收盤價列'close'的平均值。

     ts_code trade_date   open   high    low  close  pre_close  change  pct_chg         vol       amount
0  000001.SZ   20180104  13.32  13.37  13.13  13.25      13.33   -0.08    -0.60  1854509.48  2454543.516
1  000001.SZ   20180103  13.73  13.86  13.20  13.33      13.70   -0.37    -2.70  2962498.38  4006220.766
2  000001.SZ   20180102  13.35  13.93  13.32  13.70      13.30    0.40     3.01  2081592.55  2856543.822
3  600000.SH   20180104  12.70  12.73  12.62  12.66      12.66    0.00     0.00   278838.04   353205.838
4  600000.SH   20180103  12.73  12.80  12.66  12.66      12.72   -0.06    -0.47   378391.01   480954.809
5  600000.SH   20180102  12.61  12.77  12.60  12.72      12.59    0.13     1.03   313230.53   398614.966
6  000002.SZ   20180104  32.76  33.53  32.10  33.12      32.33    0.79     2.44   529085.80  1740602.533
7  000002.SZ   20180103  32.50  33.78  32.23  32.33      32.56   -0.23    -0.71   646870.20  2130249.691
8  000002.SZ   20180102  31.45  32.99  31.45  32.56      31.06    1.50     4.83   683433.50  2218502.766

grouped = stock_data.groupby('ts_code')
print(grouped['close'].mean())

ts_code
000001.SZ    13.426667
000002.SZ    32.670000
600000.SH    12.680000
Name: close, dtype: float64

② 按列'ts_code'分組,用函數(shù).sum()計算分組中收盤價漲跌幅(%)列'pct_chg'的和。

print(grouped['pct_chg'].sum())

ts_code
000001.SZ   -0.29
000002.SZ    6.56
600000.SH    0.56
Namepct_chgdtypefloat64

按列'ts_code'分組,用函數(shù).count()計算分組中收盤價列'close'的數(shù)量。

print(grouped['close'].count())

ts_code
000001.SZ    3
000002.SZ    3
600000.SH    3
Nameclosedtypeint64

④ 按列'ts_code'分組,用函數(shù).max().min()計算分組中收盤價列'close'的最大、最小值。

print(grouped['close'].max())
print(grouped['close'].min())

ts_code
000001.SZ    13.70
000002.SZ    33.12
600000.SH    12.72
Nameclosedtypefloat64

ts_code
000001.SZ    13.25
000002.SZ    32.33
600000.SH    12.66
Nameclosedtypefloat64

 按列'ts_code'分組,用函數(shù).median()計算分組中收盤價列'close'的算術(shù)中位數(shù)。

print(grouped['close'].median())

ts_code
000001.SZ    13.33
000002.SZ    32.56
600000.SH    12.66
Nameclosedtypefloat64

我們也可以用多個鍵進(jìn)行分組聚合。示例中以['ts_code', 'trade_date']為鍵,從左到右的先后順序分組,然后調(diào)用.count()函數(shù)計算分組中的數(shù)量。

by_mult = stock_data.groupby(['ts_code''trade_date'])
print(by_mult['close'].count())

ts_code    trade_date
000001.SZ  20180102      1
           20180103      1
           20180104      1
000002.SZ  20180102      1
           20180103      1
           20180104      1
600000.SH  20180102      1
           20180103      1
           20180104      1
Name: close, dtype: int64

如果不想把分組鍵設(shè)置為索引,可以向groupby傳?參數(shù)as_index=False。

by_mult = stock_data.groupby(['ts_code''trade_date'], as_index=False)
print(by_mult['close'].count())

     ts_code trade_date  close
0  000001.SZ   20180102      1
1  000001.SZ   20180103      1
2  000001.SZ   20180104      1
3  000002.SZ   20180102      1
4  000002.SZ   20180103      1
5  000002.SZ   20180104      1
6  600000.SH   20180102      1
7  600000.SH   20180103      1
8  600000.SH   20180104      1

如果想要一次應(yīng)用多個聚合函數(shù),可以調(diào)用.agg()【2】方法。

aggregated = grouped['close'].agg(['max''median'])
print(aggregated)

           close       
             max median
ts_code                
000001.SZ  13.70  13.33
000002.SZ  33.12  32.56
600000.SH  12.72  12.66

也可以對多個列一次應(yīng)用多個聚合函數(shù)。

aggregated = grouped['pre_close''close'].agg(['max''median'])
print(aggregated)

          pre_close         close       
                max median    max median
ts_code                                 
000001.SZ     13.70  13.33  13.70  13.33
000002.SZ     32.56  32.33  33.12  32.56
600000.SH     12.72  12.66  12.72  12.66

還可以對不同列應(yīng)用不同的聚合函數(shù)這里我們先自己定義一個聚合函數(shù)spread,用于計算最大值和最小值之間的差值,再調(diào)用.agg()方法,傳??個從列名映射到函數(shù)的字典。

def spread(series):
    return series.max() - series.min()

aggregator = {'close''mean''vol''sum''pct_chg': spread}
aggregated = grouped.agg(aggregator)
print(aggregated)

               close         vol  pct_chg
ts_code                                  
000001.SZ  13.426667  6898600.41     5.71
000002.SZ  32.670000  1859389.50     5.54
600000.SH  12.680000   970459.58     1.50

04

巧用apply函數(shù)

巧用apply【3】并傳入自定義函數(shù),可以實現(xiàn)更一般性的“拆分-應(yīng)用-合并”的操作,傳入的自定義函數(shù)可以是任何你想要實現(xiàn)的功能。下面舉幾個實例。

用分組平均值填充NaN值。

     ts_code trade_date         vol
0  000001.SZ   20180102  2081592.55
1  000001.SZ   20180103  2962498.38
2  000001.SZ   20180104         NaN
3  600000.SH   20180102   313230.53
4  600000.SH   20180103   378391.01
5  600000.SH   20180104         NaN
6  000002.SZ   20180102   683433.50
7  000002.SZ   20180103   646870.20
8  000002.SZ   20180104         NaN

fill_mean = lambda g: g.fillna(g.mean())
stock_data = stock_data.groupby('ts_code', as_index=False, group_keys=False).apply(fill_mean)
print(stock_data)

    ts_code trade_date          vol
0  000001.SZ   20180102  2081592.550
1  000001.SZ   20180103  2962498.380
2  000001.SZ   20180104  2522045.465
6  000002.SZ   20180102   683433.500
7  000002.SZ   20180103   646870.200
8  000002.SZ   20180104   665151.850
3  600000.SH   20180102   313230.530
4  600000.SH   20180103   378391.010
5  600000.SH   20180104   345810.770

篩選出分組中指定列具有最大值的行。

    ts_code trade_date         vol
0  000001.SZ   20180104  1854509.48
1  000001.SZ   20180103  2962498.38
2  000001.SZ   20180102  2081592.55
3  600000.SH   20180104   278838.04
4  600000.SH   20180103   378391.01
5  600000.SH   20180102   313230.53
6  000002.SZ   20180104   529085.80
7  000002.SZ   20180103   646870.20
8  000002.SZ   20180102   683433.50

def top(df, column='vol'):
    return df.sort_values(by=column)[-1:]

stock_data = stock_data.groupby('ts_code',  as_index=False, group_keys=False).apply(top)
print(stock_data)

     ts_code trade_date         vol
1  000001.SZ   20180103  2962498.38
8  000002.SZ   20180102   683433.50
4  600000.SH   20180103   378391.01

分組進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化。

    ts_code trade_date  close
0  000001.SZ   20180102  13.70
1  000001.SZ   20180103  13.33
2  000001.SZ   20180104  13.25
3  000001.SZ   20180105  13.30
4  600000.SH   20180102  12.72
5  600000.SH   20180103  12.66
6  600000.SH   20180104  12.66
7  600000.SH   20180105  12.69

min_max_tr = lambda x: (x - x.min()) / (x.max() - x.min())
stock_data['close_normalised'] = stock_data.groupby(['ts_code'])['close'].apply(min_max_tr)
print(stock_data)

     ts_code trade_date  close  close_normalised
0  000001.SZ   20180102  13.70          1.000000
1  000001.SZ   20180103  13.33          0.177778
2  000001.SZ   20180104  13.25          0.000000
3  000001.SZ   20180105  13.30          0.111111
4  600000.SH   20180102  12.72          1.000000
5  600000.SH   20180103  12.66          0.000000
6  600000.SH   20180104  12.66          0.000000
7  600000.SH   20180105  12.69          0.500000

05

總結(jié)

本文介紹了如何利用Pandas中提供的groupby功能,靈活高效地對數(shù)據(jù)集進(jìn)行分組、聚合操作,其原理是對數(shù)據(jù)進(jìn)行“拆分split-應(yīng)用apply-合并combine”的過程。

首先,介紹了常用的幾個聚合函數(shù),包括.mean(), .sum(), .count(), .max(), .min(), .median()。接著,介紹了一些較為復(fù)雜的分組聚合操作,包括用多個鍵分組,調(diào)用.agg()對多列一次應(yīng)用多個聚合函數(shù)、對不同列應(yīng)用不同的聚合函數(shù)。

最后,用幾個實例介紹了在分組聚合操作中巧用apply函數(shù)的好處。相關(guān)官方文檔鏈接已附在下面,感興趣的話可以自行查看所有可設(shè)置的參數(shù),解鎖更多新功能!

END

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多