Pandas合并: Merge, Join, Concat, Append【Pandas入门教程6】 – TuringPlanet 您所在的位置:网站首页 数据集横向合并怎么操作 Pandas合并: Merge, Join, Concat, Append【Pandas入门教程6】 – TuringPlanet

Pandas合并: Merge, Join, Concat, Append【Pandas入门教程6】 – TuringPlanet

2024-07-12 12:26| 来源: 网络整理| 查看: 265

Contents hide 1. 4种横向合并的方式(Types of joins) 2. 横向合并1:Merge 3. 横向合并2:Join 4. 纵向合并1:Concat 5. 纵向合并2:Append 无法播放?请 点击这里 跳转到Youtube 切换视频源:

结合之前的章节,我们已经掌握了常用的操作DataFrame的方法和数据分析相关的内容,这一章我们来补充学习一下如何合并DataFrame。

DataFrame合并的方法我们可以简单分为两种,一种是横向的合并,另一种是纵向的合并。那Pandas有4个方法来实现这两种合并:merge,join,concat和append,其中merge和join适用于横向的合并(axis = 1),concat和append则更适用于纵向的合并(axis = 0)。

merge可以做join的所有操作,还更灵活,concat也能完成append所有操作,同样也更灵活,所以只要熟练掌握merge和concat,就能保证你能完成对DataFrame大部分的操作了。接下来我们会重点学习merge和concat,然后简单了解一下join和append即可。

4种横向合并的方式(Types of joins)

横向合并比较复杂,没学习过SQL join相关内容的朋友可能比较费解,那首先简单介绍一下横向jon相关概念。横向合并总共有四种:Inner Join,Outer Join,Left Join和Right Join。进行Join操作的时候,要区分好左DataFrame和右DataFrame,不同的排序也会导致结果不同。

(大家不要被join这个词所困惑,这里提到的join是横向合并的方式,而pandas中merge和join是用来实现横向合并两个不同的函数,所以这里提到的join和pandas中的join函数并不是一个意思。)

Inner Join:返回一个DataFrame,只包含左右两个DataFrame共有的数据。

Outer Join (full join):返回左右DataFrame中包含的所有数据。

Left Join:返回一个DataFrame,保证其包含左DataFrame中所有的数据。

Right Join:返回一个DataFrame,保证其包含右DataFrame中所有的数据。

以上是对Join最基本的解释,接下来我们会通过具体的例子帮助大家更好地理解。

横向合并1:Merge

首先创建好用来学习的DataFrames:

import numpy as np import pandas as pd movies = pd.DataFrame({ 'movie_id': [1, 2, 3, 5, 7], 'title': ['t1', 't2', 't3', 't5', 't7'], 'description': ['d1', 'd2', 'd3', 'd5', 'd7'] }) ratings = pd.DataFrame({ 'user_id': [1, 2, 7, 9, 11, 15], 'movie_id': [1, 2, 4, 5, 6, 7], 'title': ['t1', 't2', 't3', 't4', 't5', 't6'], 'rating': [5, 4, 3, 2, 3, 1], 'time': ['t1', 't2', 't4', 't4', 't1', 't3'] })

然后使用merge函数进行最基础的inner merge:

pd.merge(movies, ratings) # 自动基于相同名字的列(movie_id和title)进行inner join,只有同名列上数值相同的行才会被结合。 pd.merge(movies, ratings, on=['movie_id', 'title']) # 和上面的结果相同,通过on参数显性定义要join的列 pd.merge(movies, ratings, on=['movie_id']) # 只基于 movie_id 列进行结合 pd.merge(movies, ratings, left_on='movie_id', right_on='user_id') # 使用左dataframe的movie_id和右dataframe的user_id进行合并 pd.merge(movies, ratings, left_index=True, right_index=True) # 基于两边的index进行merge

如果要解决列名字重合(overlapping)的问题,可以使用suffixes参数来解决: 

pd.merge(movies, ratings, on=['movie_id'], suffixes=['_left', '_right']) movie_id title_left description user_id title_right rating time 0 1 t1 d1 1 t1 5 t1 1 2 t2 d2 2 t2 4 t2 2 5 t5 d5 9 t4 2 t4 3 7 t7 d7 15 t6 1 t3

使用 how 参数来定义你要 merge 的方式,其中有四个选项(inner, outer, left, right):

pd.merge(movies, ratings, on=['movie_id', 'title'], how='inner') # 拿到基于movie_id和title两列数值相同的行 movie_id title description user_id rating time 0 1 t1 d1 1 5 t1 1 2 t2 d2 2 4 t2 pd.merge(movies, ratings, on=['movie_id', 'title'], how='outer') # 拿到两边所有的行,没有数据会被拉下,无法merge的列会被填上空值 movie_id title description user_id rating time 0 1 t1 d1 1.0 5.0 t1 1 2 t2 d2 2.0 4.0 t2 2 3 t3 d3 NaN NaN NaN 3 5 t5 d5 NaN NaN NaN 4 7 t7 d7 NaN NaN NaN 5 4 t3 NaN 7.0 3.0 t4 6 5 t4 NaN 9.0 2.0 t4 7 6 t5 NaN 11.0 3.0 t1 8 7 t6 NaN 15.0 1.0 t3 pd.merge(movies, ratings, on=['movie_id', 'title'], how='left') # 存下左Dataframe所有数值,扔掉右DataFrame中不和左DataFrame重合的行(基于movie_id和title列) movie_id title description user_id rating time 0 1 t1 d1 1.0 5.0 t1 1 2 t2 d2 2.0 4.0 t2 2 3 t3 d3 NaN NaN NaN 3 5 t5 d5 NaN NaN NaN 4 7 t7 d7 NaN NaN NaN pd.merge(movies, ratings, on=['movie_id', 'title'], how='right') # 和left join相反,存下右DataFrame所有的行,左DataFrame中不和右DataFrame重合的数据会被扔掉 movie_id title description user_id rating time 0 1 t1 d1 1 5 t1 1 2 t2 d2 2 4 t2 2 4 t3 NaN 7 3 t4 3 5 t4 NaN 9 2 t4 4 6 t5 NaN 11 3 t1 5 7 t6 NaN 15 1 t3

在做join的时候,我们也可以使用indicator来提示我们数据的情况:

pd.merge(movies, ratings, on=['movie_id', 'title'], how='outer', indicator=True) # 结果中会有一个额外的列_merge显性提示数据的情况 movie_id title description user_id rating time _merge 0 1 t1 d1 1.0 5.0 t1 both 1 2 t2 d2 2.0 4.0 t2 both 2 3 t3 d3 NaN NaN NaN left_only 3 5 t5 d5 NaN NaN NaN left_only 4 7 t7 d7 NaN NaN NaN left_only 5 4 t3 NaN 7.0 3.0 t4 right_only 6 5 t4 NaN 9.0 2.0 t4 right_only 7 6 t5 NaN 11.0 3.0 t1 right_only 8 7 t6 NaN 15.0 1.0 t3 right_only # 自定义indicator column的名称 pd.merge(movies, ratings, on=['movie_id', 'title'], how='outer', indicator='indicator_column') movie_id title description user_id rating time indicator_column 0 1 t1 d1 1.0 5.0 t1 both 1 2 t2 d2 2.0 4.0 t2 both 2 3 t3 d3 NaN NaN NaN left_only 3 5 t5 d5 NaN NaN NaN left_only 4 7 t7 d7 NaN NaN NaN left_only 5 4 t3 NaN 7.0 3.0 t4 right_only 6 5 t4 NaN 9.0 2.0 t4 right_only 7 6 t5 NaN 11.0 3.0 t1 right_only 8 7 t6 NaN 15.0 1.0 t3 right_only 横向合并2:Join

虽然merge可以完成join所有的操作,还更灵活,但是这边也简单介绍一下join,帮助大家未来也能理解相关代码。

join没有merge那么方便,此函数是基于index进行结合的:

movies.join(ratings, on='movie_id', lsuffix='_left', rsuffix='_right') # 使用左DataFrame的movie_id和右DataFrame的index进行结合,默认是left join pd.merge(movies, ratings, left_on='movie_id', right_index=True, how='left') # 执行结果和上面语句一样

如果想要基于特定的列进行结合,可以改变index后再进行操作:

movies.set_index('movie_id').join(ratings.set_index('movie_id'), lsuffix='_left', rsuffix='_right') # 基于movie_id进行left join movies.merge(ratings, on='movie_id', how='left') # 执行结果和上面一样

因为merge比join更容易理解,而且操作,推荐大家直接使用merge代替join进行横向合并。

纵向合并1:Concat

上面提到的Merge和join用于实现横向合并,而接下来学习的Concat和Append主要是用来实现纵向合并。而其中Concat比Append功能更多,所以大家重点掌握Concat就好。

使用Concat实现纵向合并(将两个 DataFrame 按照水平方向叠起来):

pd.concat([movies, ratings]) # 纵向结合两个DataFrame,index不会被reset pd.concat([movies, ratings], ignore_index = True) # index会被reset

我们也能使用 concat 进行 inner join 和 outer join(没有left join和right join,default是outer join):

pd.concat([movies, ratings], axis=1) # 将axis设为1后,可基于index进行outer join,但不是真正意义上的join,只是横向水平叠合 movie_id title description user_id movie_id title rating time 0 1.0 t1 d1 1 1 t1 5 t1 1 2.0 t2 d2 2 2 t2 4 t2 2 3.0 t3 d3 7 4 t3 3 t4 3 5.0 t5 d5 9 5 t4 2 t4 4 7.0 t7 d7 11 6 t5 3 t1 5 NaN NaN NaN 15 7 t6 1 t3 pd.concat([movies, ratings], join='inner', axis=1) # 基于index进行inner join pd.concat([movies.set_index('movie_id'), ratings.set_index('movie_id')], join='inner', axis=1) # 基于movie_id进行inner join pd.merge(movies, ratings, on='movie_id') # 执行结果和上面一样

将 axis 设为 0,则会实现纵向结合的操作:

pd.concat([movies, ratings], axis=0, join='inner') # 纵向inner结合 纵向合并2:Append

因为 concat 能实现 append 中的所有操作,所以纵向操作直接交给 concat 就好。那这边也简单来了解一下Append函数:

# 将rating合并到movies底下,并重置index movies.append(ratings, ignore_index = True) pd.concat([movies, ratings], ignore_index = True) # 执行结果和上面一样 movie_id title description user_id rating time 0 1 t1 d1 NaN NaN NaN 1 2 t2 d2 NaN NaN NaN 2 3 t3 d3 NaN NaN NaN 3 5 t5 d5 NaN NaN NaN 4 7 t7 d7 NaN NaN NaN 5 1 t1 NaN 1.0 5.0 t1 6 2 t2 NaN 2.0 4.0 t2 7 4 t3 NaN 7.0 3.0 t4 8 5 t4 NaN 9.0 2.0 t4 9 6 t5 NaN 11.0 3.0 t1 10 7 t6 NaN 15.0 1.0 t3 # 将ratings和movies自己合并到movies下面,并重置index movies.append([ratings, movies], ignore_index = True) movie_id title description user_id rating time 0 1 t1 d1 NaN NaN NaN 1 2 t2 d2 NaN NaN NaN 2 3 t3 d3 NaN NaN NaN 3 5 t5 d5 NaN NaN NaN 4 7 t7 d7 NaN NaN NaN 5 1 t1 NaN 1.0 5.0 t1 6 2 t2 NaN 2.0 4.0 t2 7 4 t3 NaN 7.0 3.0 t4 8 5 t4 NaN 9.0 2.0 t4 9 6 t5 NaN 11.0 3.0 t1 10 7 t6 NaN 15.0 1.0 t3 11 1 t1 d1 NaN NaN NaN 12 2 t2 d2 NaN NaN NaN 13 3 t3 d3 NaN NaN NaN 14 5 t5 d5 NaN NaN NaN 15 7 t7 d7 NaN NaN NaN pd.concat([movies, ratings, movies], ignore_index = True) # 执行结果和上面一样

如果要将结果按照列名排序,请将sort参数设为True:

movies.append(ratings, sort = True)

以上就是merge, join, concat, append相关的内容了,如果大家想要更好地理解这章知识点,可以通过操作前几章常用的survey_df进行复习:

csv_data_path = 'https://raw.githubusercontent.com/turingplanet/pandas-intro/main/public-datasets/small_survey_results.csv' survey_df = pd.read_csv(csv_data_path) # 此数据集包含了StackOverflow上随机的1000份用户调研(列名的具体含义请参考:https://github.com/turingplanet/pandas-intro/blob/main/public-datasets/survey_results_schema.csv)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有