pandas包最强大的函数之一,当属groupby了。但是大多数人对groupby函数研究是很少的,只会使用其中的一小部分功能。
groupby函数允许对数据集采用拆分-应用-组合的方法。这种方法通常用于对数据进行切片和分块,以便数据分析师能够回答特定的问题。
groupby可以做到:
本次深度总结主要有以下两个部分:
本文为系列(1),总结groupby分组数据,代码采用jupyter notebook演示。
我们使用一个虚构的销售部门的数据。该数据集包括虚构的销售代表、订单引导、交易可能完成的公司、订单值和引导日期等列。
输入:
order_leads = pd.read_csv(
'https://raw.githubusercontent.com/FBosler/Medium-Data-Exploration/master/order_leads.csv',
parse_dates = [3]
)
sales_team = pd.read_csv(
'https://raw.githubusercontent.com/FBosler/Medium-Data-Exploration/master/sales_team.csv',
parse_dates = [3]
)
df = pd.merge(order_leads,sales_team,on=['Company Id','Company Name'])
df = df.rename(columns={'Order Value':'Val','Converted':'Sale'})
df
输出:
Order Id Company Id Company Name Date Val Sale Sales Rep Sales Rep Id
0 HZSXLI1IS9RGABZW D0AUXPP07H6AVSGD Melancholy Social-Role 2017-10-13 6952 0 William Taylor ZTZA0ZLYZR85PTUJ
1 582WPS3OW8T6YT0R D0AUXPP07H6AVSGD Melancholy Social-Role 2017-09-02 7930 0 William Taylor ZTZA0ZLYZR85PTUJ
2 KRF65MQZBOYG4Y9T D0AUXPP07H6AVSGD Melancholy Social-Role 2016-12-21 5538 1 William Taylor ZTZA0ZLYZR85PTUJ
3 N3EDZ5V1WGSWW828 D0AUXPP07H6AVSGD Melancholy Social-Role 2018-06-03 1113 0 William Taylor ZTZA0ZLYZR85PTUJ
4 QXBC8COXEXGFSPLP D0AUXPP07H6AVSGD Melancholy Social-Role 2014-07-26 4596 0 William Taylor ZTZA0ZLYZR85PTUJ
... ... ... ... ... ... ... ... ...
99995 HKZFX556ZQRZJZWR APH243SK72T90MPS Trade-Preparatory Quarterbacks 2017-11-06 7516 0 Ida Woodward LF3CPWWZKSNB1AXI
99996 962CSDMAJ49E0CRK APH243SK72T90MPS Trade-Preparatory Quarterbacks 2018-08-02 442 1 Ida Woodward LF3CPWWZKSNB1AXI
99997 ZW7RO9TLL6EVVJEC APH243SK72T90MPS Trade-Preparatory Quarterbacks 2014-11-02 8544 0 Ida Woodward LF3CPWWZKSNB1AXI
99998 LNKGIWMZ9RT49IE9 APH243SK72T90MPS Trade-Preparatory Quarterbacks 2017-04-01 6650 0 Ida Woodward LF3CPWWZKSNB1AXI
99999 X9Y21H4JWX6OGC2Z APH243SK72T90MPS Trade-Preparatory Quarterbacks 2016-07-27 953 0 Ida Woodward LF3CPWWZKSNB1AXI
100000 rows × 8 columns
调用groupby的默认方法是明确提供列名以拆分数据集。然而,这是鲜为人知的是,也可以传递一个Series数据到groupby来分组。唯一限制是该Series与DataFrame具有相同的长度。这意味着可以通过列的已处理版本进行组,而无需为此创建新的辅助列。
输入:
grouped = df.groupby('Sales Rep')
grouped
输出:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f3b06e835e0>
现在创建了一个dataframe的groupby对象。 让我们进一步分析:
调用分组对象上的组返回每个组的索引列表(因为每行可以通过其索引唯一识别)
输入:
grouped.groups
输出:
{
'Aaron Hendrickson': Int64Index(
[25612, 25613, 25614, 25615, 25616, 25617, 25618, 25619, 25620, 25621,..., 25894, 25895, 25896, 25897, 25898, 25899, 25900, 25901, 25902, 25903], dtype='int64', length=292
),
'Adam Sawyer': Int64Index(
[67140, 67141, 67142, 67143, 67144, 67145, 67146, 67147, 67148, 67149, ..., 67454, 67455, 67456, 67457, 67458, 67459, 67460, 67461, 67462, 67463], dtype='int64', length=324
),
...
'Yvonne Lindsey': Int64Index([20384, 20385, 20386, 20387, 20388, 20389, 20390, 20391, 20392, 20393, 20394, 20395, 20396, 20397, 20398, 20399, 20400, 20401, ... , 20447, 20448, 20449, 20450], dtype='int64', length=67)
}
调用get_group函数,可以返回相应的数据子集。
输入:
grouped.get_group('Aaron Hendrickson')
输出:
Order Id Company Id Company Name Date Val Sale Sales Rep Sales Rep Id
25612 3BJY12LWBN7D0GJL CE4544HJOFMONMH2 Follow-Up Boundary 2014-09-04 1940 0 Aaron Hendrickson AEMLQ09IYM72ACBL
25613 W3HHOSC1H6A1PW37 CE4544HJOFMONMH2 Follow-Up Boundary 2015-09-24 2109 0 Aaron Hendrickson AEMLQ09IYM72ACBL
25614 G9JKIZO4WD945GBH CE4544HJOFMONMH2 Follow-Up Boundary 2014-12-06 4300 1 Aaron Hendrickson AEMLQ09IYM72ACBL
25615 BKIJVKZ7REVN6P8B CE4544HJOFMONMH2 Follow-Up Boundary 2017-05-07 3026 0 Aaron Hendrickson AEMLQ09IYM72ACBL
25616 WFHGWR4PAD04A2GJ CE4544HJOFMONMH2 Follow-Up Boundary 2016-01-20 5033 0 Aaron Hendrickson AEMLQ09IYM72ACBL
... ... ... ... ... ... ... ... ...
25899 NATK7K3TZUH32BBE CGDGXAW6GNU6JIEG Fiftieth Art'S 2015-01-27 6095 1 Aaron Hendrickson AEMLQ09IYM72ACBL
25900 EGD6IRB0UML62XB0 CGDGXAW6GNU6JIEG Fiftieth Art'S 2018-11-04 7652 1 Aaron Hendrickson AEMLQ09IYM72ACBL
25901 9Z18A7D1T8EUH58D CGDGXAW6GNU6JIEG Fiftieth Art'S 2016-05-08 4746 0 Aaron Hendrickson AEMLQ09IYM72ACBL
25902 R0LUW64V2F3O2HSD CGDGXAW6GNU6JIEG Fiftieth Art'S 2017-02-16 6158 0 Aaron Hendrickson AEMLQ09IYM72ACBL
25903 UMHMBM5M179IHX6D CGDGXAW6GNU6JIEG Fiftieth Art'S 2017-07-28 2164 0 Aaron Hendrickson AEMLQ09IYM72ACBL
292 rows × 8 columns
为了演示一些高级分组功能,将通过使用apply步骤的最简单版本:size方法(计算每个组中的行数)。这样做可以专注于groupby的应用。
输入:
grouped.size()
输出:
Sales Rep
Aaron Hendrickson 292
Adam Sawyer 324
Adele Kimmel 115
Adrian Daugherty 369
Adrianna Shelton 37
...
Willie Lin 44
Willie Rau 95
Willie Sanchez 309
Yvonne Jones 74
Yvonne Lindsey 67
Length: 499, dtype: int64
下面的例子是通过’Sales Rep’这个列的变体分组。原来的分组方法只能是通过创建辅助列的方法来分组,这个方法可以避免修改原数据,保证原数据不被污染。
通过使用str方法提取人名中的姓。
输入:
df.groupby(
df['Sales Rep'].str.split(' ').str[0]
).size()
输出:
Sales Rep
Aaron 292
Adam 324
Adele 115
Adrian 369
Adrianna 37
...
Wesley 144
Wilbert 213
William 1393
Willie 448
Yvonne 141
Length: 318, dtype: int64
输入:
df.groupby(
df['Sales Rep'].apply(lambda x: 'William' in x)
).size()
输出:
Sales Rep
False 97111
True 2889
dtype: int64
输入:
df.groupby(
pd.Series(np.random.choice(list('ABCDG'),len(df)))
).size()
输出:
A 19852
B 19949
C 20184
D 19912
G 20103
dtype: int64
输入:
df.groupby(
pd.qcut(x=df['Val'],q=3,labels=['low','mid','high'])
).size()
输出:
Val
low 33339
mid 33336
high 33325
dtype: int64
输入:
df.groupby(
pd.cut(df['Val'],[0,3000,5000,7000,10000])
).size()
输出:
Val
(0, 3000] 29220
(3000, 5000] 19892
(5000, 7000] 20359
(7000, 10000] 30529
dtype: int64
pd.Grouper是很重要的一个函数,在处理时间序列数据时非常有用。
api使用样例:pd.Grouper(key=, freq=),通过该函数可以根据指定列的指定时间频率对数据进行分组。本例中对’Date’列按’Y’进行分组。
输入:
df.groupby(pd.Grouper(key='Date',freq='Y')).size()
输出:
Date
2014-12-31 19956
2015-12-31 20054
2016-12-31 20133
2017-12-31 20079
2018-12-31 19778
Freq: A-DEC, dtype: int64
除了按’Y’分组,还可以按’D’,‘W’,‘M’,或者’Q’分组,具体如下表:
df.groupby(pd.Grouper(key='Date',freq='SM')).size()
输出:
Date
2013-12-31 761
2014-01-15 837
2014-01-31 820
2014-02-15 740
2014-02-28 817
...
2018-10-31 810
2018-11-15 805
2018-11-30 824
2018-12-15 837
2018-12-31 50
Freq: SM-15, Length: 121, dtype: int64
输入:
df.groupby(['Sales Rep','Company Name']).size()
输出:
Sales Rep Company Name
Aaron Hendrickson 6-Foot Homosexuals 20
63D House'S 27
Angular Liberalism 28
Boon Blish'S 18
Business-Like Structures 21
..
Yvonne Jones Entry-Limiting Westinghouse 20
Intractable Fairgoers 18
Smarter Java 17
Yvonne Lindsey Meretricious Fabrication 28
Shrill Co-Op 39
Length: 4619, dtype: int64