"); //-->
在日常工作中,我们可能会从多个数据集中获取数据,并且希望合并两个或多个不同的数据集。这时就可以使用Pandas包中的Merge函数。在本文中,我们将介绍用于合并数据的三个函数merge、merge_ordered、merge_asof。
mergemerge函数是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数据结合起来。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。