Pandas groupby操作和分组内排序
在本文中,我们将介绍Pandas的groupby操作与分组内排序的使用方法。
Pandas中的groupby操作可以非常方便地实现数据的分组统计,是数据清洗和特征工程的常用操作,而分组内排序则是groupby操作的一个常见需求。下面我们通过一个例子来介绍这两个操作。
阅读更多:Pandas 教程
简单例子
考虑下面的数据集:
import pandas as pd
df = pd.DataFrame({'Name': ['Alice', 'Bob', 'Charlie', 'David'] * 2,
'Group': ['A', 'A', 'B', 'B'] * 2,
'Value': [2, 3, 1, 4, 0, 1, 3, 2]})
print(df)
输出:
Name Group Value
0 Alice A 2
1 Bob A 3
2 Charlie B 1
3 David B 4
4 Alice A 0
5 Bob A 1
6 Charlie B 3
7 David B 2
这是一个包含姓名、组别和数值的数据集,我们的目标是按组别分组后,根据数值排序。也就是对于每个组别,都要把对应行按数值大小排个序。
首先进行分组,然后使用apply方法进行分组内排序:
df.groupby('Group').apply(lambda x: x.sort_values('Value'))
输出:
Name Group Value
Group
A 4 Alice A 0
5 Bob A 1
0 Alice A 2
1 Bob A 3
B 2 Charlie B 1
7 David B 2
6 Charlie B 3
3 David B 4
可以看到,我们成功地按组别进行了分组、排序操作。
复杂例子
接下来考虑一个稍微复杂一点的例子。
我们有一份销售数据集,包含订单号、用户ID、商品名称、数量和金额等信息。现在的问题是,我们想要按用户ID分组后,按订单金额均值排序,同时显示每个用户的订单总数和商品数量总数。
数据集如下:
import pandas as pd
import numpy as np
np.random.seed(0)
df_sales = pd.DataFrame({'OrderID': np.random.randint(100, 110, size=20),
'UserID': ['U1', 'U1', 'U2', 'U2', 'U2', 'U3', 'U3', 'U3', 'U4', 'U4', 'U5', 'U5', 'U5', 'U6', 'U6', 'U6', 'U7', 'U7', 'U8', 'U9'],
'Product': np.random.choice(['A', 'B', 'C'], 20),
'Quantity': np.random.randint(1, 5, size=20),
'Price': np.random.randint(10, 50, size=20)})
print(df_sales)
输出:
OrderID UserID Product Quantity Price
0 107 U1 B 2 18
1 103 U1 A 4 39
2 103 U2 A 3 12
3 105 U2 C 3 32
4 100 U2 C 1 21
5 106 U3 C 4 45
6 106 U3 A 1 21
7 109 U3 A 4 21
8 107 U4 C 2 27
9 105 U4 C 1 20
10 107 U5 A 3 11
11 109 U5 C 1 35
12 108 U5 A 1 42
13 100 U6 A 3 39
14 108 U6 B 2 10
15 100 U6 A 2 35
16 109 U7 A 1 22
17 102 U7 C 2 14
18 108 U8 A 2 28
19 100 U9 A 4 46
首先进行分组,并计算订单数和商品数:
df_grouped = df_sales.groupby('UserID').agg({'OrderID': 'count',
'Product': 'sum',
'Price': 'mean'})
回顾一下上面这个语句。我们使用了groupby方法按UserID进行分组,然后使用agg进行聚合操作。agg的参数是一个字典,键表示要进行聚合的列名,值表示对应的聚合方法。
OrderID的聚合方法是count,这意味着计算订单数。Product的聚合方法是sum,这意味着把每个用户买的商品名称拼接起来。最后,Price的聚合方法是mean,也就是计算订单金额均值。
接下来,我们对每个用户的数据按Price进行排序,并重新命名列名。最后,我们把订单数和商品数与排序后的数据合并在一起。
df_final = df_grouped.sort_values('Price', ascending=False).rename(columns={'OrderID': 'OrderCount',
'Product': 'ProductList',
'Price': 'OrderAmount'})
df_final = pd.concat([df_sales['UserID'].value_counts(), df_final], axis=1)
df_final.rename(columns={'UserID': 'ProductCount'}, inplace=True)
第一次concat的作用是取出每个用户的数据,第二次concat的作用是把订单数和商品数与排序后的数据合并在一起。注意最后一行代码的作用是更改列名。
输出最终结果:
print(df_final)
结果:
ProductCount OrderCount ProductList OrderAmount
U2 3 3 ACC 21.666667
U5 3 3 ACA 29.333333
U3 3 3 CAA 29.000000
U1 2 2 BA 28.500000
U6 3 3 AAB 27.333333
U4 2 2 CC 23.500000
U7 2 2 CA 18.000000
U8 1 1 A 28.000000
U9 1 1 A 46.000000
总结
本文介绍了Pandas中的groupby操作和分组内排序的使用方法。通过上面的例子,我们可以清楚地看到,这两个操作非常实用,可以帮助我们快速地进行数据清洗和特征工程。希望本文能够帮助读者更好地掌握Pandas的使用。
极客笔记