新闻  |   论坛  |   博客  |   在线研讨会
Pandas 的Merge函数详解(1)
数据派THU | 2023-08-22 20:03:09    阅读:1496   发布文章

在日常工作中,我们可能会从多个数据集中获取数据,并且希望合并两个或多个不同的数据集。这时就可以使用Pandas包中的Merge函数。在本文中,我们将介绍用于合并数据的三个函数merge、merge_ordered、merge_asof。

图片

merge

merge函数是Pandas中执行基本数据集合并的首选函数。函数将根据给定的数据集索引或列组合两个数据集。

我们使用下面试示例:

 import pandas as pd
 customer = pd.DataFrame({'cust_id': [1,2,3,4,5],                    'cust_name': ['Maria', 'Fran', 'Dominique', 'Elsa', 'Charles'],                    'country': ['German', 'Spain', 'Japan', 'Poland', 'Argentina']})
 order = pd.DataFrame({'order_id': [200, 201,202,203,204],                      'cust_id':[1,3,3,4,2],                      'order_date': ['2014-07-05', '2014-07-06', '2014-07-07', '2014-07-07', '2014-07-08'],                      'order_value': [10.1, 20.5, 18.7, 19.1, 13.5]})

图片

我们尝试模拟两个不同的数据集:客户和订单数据,其中cust_id列同时存在于两个DataFrame中。

 pd.merge(customer, order)

图片

默认情况下,merge函数是这样工作的:

将按列合并,并尝试从两个数据集中找到公共列,使用来自两个DataFrame(内连接)的列值之间的交集。

列和索引合并

在上面合并的数据集中,merge函数在cust_id列上连接两个数据集,因为它是唯一的公共列。我们也可以指定要在两个数据集上连接的列名。

如果两个列的名称都存在于两个DataFrame中,则可以使用参数on。



 pd.merge(customer, order, on = 'cust_id')



结果与前面的示例类似,因为cust_id是唯一的公共列。但是如果两个DataFrame都包含两个或多个具有相同名称的列,则这个参数就很重要。


我们来创建一个包含两个相似列的数据。

customer = pd.DataFrame({'cust_id': [1,2,3,4,5],                    'cust_name': ['Maria', 'Fran', 'Dominique', 'Elsa', 'Charles'],                    'country': ['German', 'Spain', 'Japan', 'Poland', 'Argentina']})
 order = pd.DataFrame({'order_id': [200, 201,202,203,204],                      'cust_id':[1,3,3,4,2],                      'order_date': ['2014-07-05', '2014-07-06', '2014-07-07', '2014-07-07', '2014-07-08'],                      'order_value': [10.1, 20.5, 18.7, 19.1, 13.5],                      'country' : ['German', 'Indonesia', 'Armenia', 'Singapore', 'Japan']                      })

图片

数据集现在包含两个名称相似的列:cust_id和country。让我们看看如果使用默认方法合并两个DataFrame会发生什么。



 pd.merge(customer, order)


图片


只剩下一行了,这是因为merge函数将使用与键名相同的所有列来合并两个数据集。所以现在是通过cust_id和country中找到的相同值来实现合并的。

还有一个问题,我们指定一个列后,其他的重复列(这里是country),现在存在country_x和country_y列。这两列是来自各自数据集的国家列。country_x来自Customer数据集,country_y来自Order数据集。

为了帮助区分合并过程中相同列名的结果,我们可以将一个元组对象传递给suffix参数。

 pd.merge(customer, order, on ='cust_id', suffixes = ('_customer', '_order'))

图片

使用suffix参数,可以让我们避免混淆,或者在合并前我们直接将列改名。

 customer = customer.rename(columns = {'country':'customer_country'})  order = order.rename(columns = {'country':'delivery_country'})

图片

这样就不会造成混淆了。

然是如果我们要合并的列名在两个数据集不同时,on参数就没有效果了,这时就需要使用left_on和right_on参数,我们这里以刚刚改名的country列为例:

 pd.merge(customer, order, left_on = 'customer_country', right_on = 'delivery_country', suffixes = ('_customer', '_order'))

图片

在上面的代码中,我们将左侧数据集(Customer)上想要合并的列传递给left_on参数,将右侧数据集(Order)的列名传递给right_on参数。

left_on和right_on参数是串联工作的,因此我们不能在left_on参数中传递列名,而将right_on参数保留为空。

我们也可以使用left_index和right_index来替换left_on和right_on参数。right_index和left_index参数控制merge函数,以根据索引而不是列连接数据集。

 pd.merge(customer, order, left_index = True, right_on = 'cust_id', suffixes = ('_customer', '_order'))

图片

在上面的代码将True值传递给left_index参数,表示希望使用左侧数据集上的索引作为连接键。合并过程类似于下图。

图片

当我们按索引和列合并时,DataFrame结果将由于合并(匹配的索引)会增加一个额外的列。

合并类型介绍

默认情况下,当我们合并数据集时,merge函数将执行Inner Join。在Inner Join中,根据键之间的交集选择行。匹配在两个键列或索引中找到的相同值。

下图显示了Inner Join图,其中只选择了Customer和Order数据集上的列和/或索引之间匹配的值。

 pd.merge(customer, order, left_on = 'customer_country',          right_on = 'delivery_country', suffixes = ('_customer', '_order'),        how = 'inner')

图片

我们也可以使用左连接和右连接来保留想要的DataFrame。

 pd.merge(customer, order, left_on = 'customer_country',        right_on = 'delivery_country', suffixes = ('_customer', '_order'),         how = 'left', indicator = True)

图片

上面的代码,所有与订单数据值不匹配的客户数据值都用NaN值填充。

indicator=True参数,将创建_merge列。在上面的结果中,可以看到两个值都表明该行来自DataFrame和left_only的交集,其中该行来自第一个DataFrame(左侧)。

如果要执行右连接,可以使用以下代码。

 pd.merge(customer, order, left_on = 'customer_country',       right_on = 'delivery_country', suffixes = ('_customer', '_order'),        how = 'right', indicator = True)

图片

还可以在合并过程中使用外连接来保留两个DataFrame。我们可以把外连接看作是同时进行的左连接和右连接。

图片

最后就是交叉连接,将合并两个DataFrame之间的每个数据行。

让我们用下面的代码尝试交叉连接。

 pd.merge(customer, order, how = 'cross', suffixes = ('_customer', '_order'))

图片

DataFrame将Customer数据中的每一行都与Order数据结合起来。


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客