Python Pandas ŌĆō 将具有一对多关系的 DataFrame 合并
在 Python Pandas 中,合并数据是一个非常常见的操作。我们可以将两个或多个 DataFrame 按照一定的规则合并成一个。而在实际的数据处理中,经常会遇到一对多的数据关系,即两个 DataFrame 中的一条数据对应另一个 DataFrame 中的多条数据。本文将介绍如何使用 Python Pandas 中的 merge 和 groupby 函数,将具有一对多关系的 DataFrame 进行合并。
示例数据介绍
我们假设现在有两个 DataFrame,一个是 orders,一个是 items。其中 orders 中包含了订单的基本信息,如订单 ID、订单日期、订单总金额等;而 items 则包含了订单中每个商品的详细信息,如商品名称、价格等。两个 DataFrame 的关系是一对多的,即一个订单对应了多个商品。
其中 orders 的数据如下:
import pandas as pd
orders_data = {
'order_id': ['1001', '1002', '1003', '1004', '1005'],
'order_date': ['2022-01-01', '2022-01-03', '2022-01-05', '2022-01-07', '2022-01-09'],
'total_amount': [1100, 2400, 1200, 800, 1600]
}
orders = pd.DataFrame(orders_data)
print(orders)
输出结果:
order_id | order_date | total_amount | |
---|---|---|---|
0 | 1001 | 2022-01-01 | 1100 |
1 | 1002 | 2022-01-03 | 2400 |
2 | 1003 | 2022-01-05 | 1200 |
3 | 1004 | 2022-01-07 | 800 |
4 | 1005 | 2022-01-09 | 1600 |
而 items 的数据如下:
items_data = {
'order_id': ['1001', '1001', '1002', '1002', '1002', '1003', '1004', '1005', '1005', '1005'],
'item_name': ['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8', 'item9', 'item10'],
'item_price': [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
}
items = pd.DataFrame(items_data)
print(items)
输出结果:
order_id | item_name | item_price | |
---|---|---|---|
0 | 1001 | item1 | 100 |
1 | 1001 | item2 | 200 |
2 | 1002 | item3 | 300 |
3 | 1002 | item4 | 400 |
4 | 1002 | item5 | 500 |
5 | 1003 | item6 | 600 |
6 | 1004 | item7 | 700 |
7 | 1005 | item8 | 800 |
8 | 1005 | item9 | 900 |
9 | 1005 | item10 | 1000 |
merge 函数的使用
在上述例子中,orders 和 items 两个 DataFrame 的共同列是 order_id。我们可以使用 merge 函数按照 order_id 进行合并。
merged_data = pd.merge(orders, items, on='order_id')
print(merged_data)
可以看出,在合并后的 DataFrame 中,每个订单对应了多个商品,并且订单信息(order_id、order_date、total_amount)都重复了。如果想要去掉这些重复的信息,我们可以使用 drop_duplicates 函数。
merged_data = merged_data.drop_duplicates(['order_id', 'item_name'])
print(merged_data)
输出结果:
order_id | order_date | total_amount | item_name | item_price | |
---|---|---|---|---|---|
0 | 1001 | 2022-01-01 | 1100 | item1 | 100 |
1 | 1001 | 2022-01-01 | 1100 | item2 | 200 |
2 | 1002 | 2022-01-03 | 2400 | item3 | 300 |
3 | 1002 | 2022-01-03 | 2400 | item4 | 400 |
4 | 1002 | 2022-01-03 | 2400 | item5 | 500 |
5 | 1003 | 2022-01-05 | 1200 | item6 | 600 |
6 | 1004 | 2022-01-07 | 800 | item7 | 700 |
7 | 1005 | 2022-01-09 | 1600 | item8 | 800 |
8 | 1005 | 2022-01-09 | 1600 | item9 | 900 |
9 | 1005 | 2022-01-09 | 1600 | item10 | 1000 |
groupby 函数的使用
另一种解决一对多关系的问题的方法是使用 groupby 函数。我们可以先将 items 按照 order_id 进行分组,然后对每组进行处理,得到每个订单对应的商品明细。
grouped_data = items.groupby('order_id')
for order_id, group in grouped_data:
print(f"Order ID: {order_id}")
print(group)
输出结果:
Order ID: 1001
order_id item_name item_price
0 1001 item1 100
1 1001 item2 200
Order ID: 1002
order_id item_name item_price
2 1002 item3 300
3 1002 item4 400
4 1002 item5 500
Order ID: 1003
order_id item_name item_price
5 1003 item6 600
Order ID: 1004
order_id item_name item_price
6 1004 item7 700
Order ID: 1005
order_id item_name item_price
7 1005 item8 800
8 1005 item9 900
9 1005 item10 1000
可以看到,groupby 函数将 items 按照 order_id 分组后,每组的数据都变成了一个新的 DataFrame。这样我们就可以对每个订单进行操作,得到相应的商品明细。
如果要将 items 分组后的结果与 orders 合并,我们可以将 groupby 结果转换为 DataFrame,然后再使用 merge 函数进行合并。
grouped_data = items.groupby('order_id').apply(lambda x: x.reset_index(drop=True))
grouped_data = grouped_data.rename(columns={'item_name': 'item_names', 'item_price': 'item_prices'})
merged_data = pd.merge(orders, grouped_data, on='order_id')
print(merged_data)
输出结果如下:
order_id | order_date | total_amount | item_names | item_prices | |
---|---|---|---|---|---|
0 | 1001 | 2022-01-01 | 1100 | [‘item1’, ‘item2’] | [100, 200] |
1 | 1002 | 2022-01-03 | 2400 | [‘item3’, ‘item4’, ‘item5’] | [300, 400, 500] |
2 | 1003 | 2022-01-05 | 1200 | [‘item6’] | [600] |
3 | 1004 | 2022-01-07 | 800 | [‘item7’] | [700] |
4 | 1005 | 2022-01-09 | 1600 | [‘item8’, ‘item9’, ‘item10’] | [800, 900, 1000] |
这样,我们就得到了一个合并了 orders 和 items 数据的 DataFrame。在新的 DataFrame 中,可以看到每个订单对应的商品明细已经用一个列表来表示,而且不用担心订单信息的重复。
注:这里我们使用了 apply 函数将 groupby 的结果转换为 DataFrame,并将原来的 index 重置了。
结论
本文介绍了如何使用 Python Pandas 中的 merge 和 groupby 函数,将具有一对多关系的 DataFrame 合并。在实际数据处理中,我们经常会遇到这种数据关系,因此掌握这种操作方法是非常必要的。同时,也需要注意去重和转换数据格式等问题,确保合并后的数据符合我们的需求。