Pandas groupby操作和分组内排序

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的使用。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程