Python Pandas ŌĆō 将具有一对多关系的 DataFrame 合并

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 合并。在实际数据处理中,我们经常会遇到这种数据关系,因此掌握这种操作方法是非常必要的。同时,也需要注意去重和转换数据格式等问题,确保合并后的数据符合我们的需求。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程