![]()
34. join 方法
1. 概述
join是 DataFrame 的方法,专门用于基于索引进行合并。它比merge更简洁,特别适合按行索引连接两个 DataFrame。
importpandasaspdimportnumpyasnp# 创建示例数据np.random.seed(42)
2. join 基础用法
2.1 基本语法
# 创建两个以索引为键的 DataFramedf1=pd.DataFrame({'姓名':['张三','李四','王五','赵六'],'年龄':[25,30,28,32]},index=['A','B','C','D'])df2=pd.DataFrame({'城市':['北京','上海','广州','深圳'],'工资':[8000,12000,10000,15000]},index=['A','B','C','E'])print("df1:")print(df1)print("\ndf2:")print(df2)# 默认左连接(基于索引)result=df1.join(df2)print("\n左连接结果:")print(result)
2.2 连接方式
# 左连接(默认)left_join=df1.join(df2,how='left')print("左连接:")print(left_join)# 右连接right_join=df1.join(df2,how='right')print("\n右连接:")print(right_join)# 内连接inner_join=df1.join(df2,how='inner')print("\n内连接:")print(inner_join)# 外连接outer_join=df1.join(df2,how='outer')print("\n外连接:")print(outer_join)
3. join vs merge 对比
# merge 方式merge_result=pd.merge(df1,df2,left_index=True,right_index=True,how='left')print("merge 方式:")print(merge_result)# join 方式(更简洁)join_result=df1.join(df2,how='left')print("\njoin 方式:")print(join_result)print("\n结果相同:",merge_result.equals(join_result))
4. 使用列作为连接键
join也可以使用列作为连接键(通过on参数)。
# 创建使用列作为键的数据df_left=pd.DataFrame({'员工ID':[101,102,103,104],'姓名':['张三','李四','王五','赵六'],'部门ID':[1,2,1,3]})df_right=pd.DataFrame({'部门ID':[1,2,3,4],'部门名称':['技术部','销售部','市场部','人事部']},index=[1,2,3,4])# 索引与连接键不同print("左表:")print(df_left)print("\n右表:")print(df_right)# 左表用列,右表用索引result=df_left.join(df_right,on='部门ID',how='left')print("\n使用 on 参数:")print(result)
5. 多 DataFrame 连接
# 创建多个 DataFramedf_base=pd.DataFrame({'ID':[1,2,3,4]},index=['A','B','C','D'])df_info1=pd.DataFrame({'姓名':['张三','李四','王五','赵六']},index=['A','B','C','D'])df_info2=pd.DataFrame({'年龄':[25,30,28,32]},index=['A','B','C','D'])df_info3=pd.DataFrame({'城市':['北京','上海','广州','深圳']},index=['A','B','C','D'])# 链式 joinresult=df_base.join([df_info1,df_info2,df_info3])print("多 DataFrame 连接:")print(result)
6. 处理重复列名
# 创建有重复列名的数据df_a=pd.DataFrame({'共同列':[1,2,3],'值A':['A1','A2','A3']},index=['X','Y','Z'])df_b=pd.DataFrame({'共同列':[2,3,4],'值B':['B2','B3','B4']},index=['Y','Z','W'])print("df_a:")print(df_a)print("\ndf_b:")print(df_b)# 默认添加后缀result=df_a.join(df_b,how='outer',lsuffix='_左',rsuffix='_右')print("\n带后缀的连接:")print(result)
7. 完整示例:员工信息整合
# 创建多个数据源print("="*60)print("员工信息整合")print("="*60)# 基础信息basic_info=pd.DataFrame({'员工ID':[1001,1002,1003,1004,1005],'姓名':['张三','李四','王五','赵六','钱七']}).set_index('员工ID')# 部门信息dept_info=pd.DataFrame({'员工ID':[1001,1002,1003,1004,1005],'部门':['技术部','销售部','技术部','市场部','销售部']}).set_index('员工ID')# 薪资信息salary_info=pd.DataFrame({'员工ID':[1001,1002,1003,1004,1006],'工资':[8000,12000,10000,15000,11000]}).set_index('员工ID')# 绩效信息performance_info=pd.DataFrame({'员工ID':[1001,1002,1003,1005,1006],'绩效':['A','B','A','B','C']}).set_index('员工ID')print("基础信息:")print(basic_info)print("\n部门信息:")print(dept_info)print("\n薪资信息:")print(salary_info)print("\n绩效信息:")print(performance_info)# 1. 逐步整合print("\n1. 整合基础+部门:")result=basic_info.join(dept_info,how='left')print(result)# 2. 整合薪资print("\n2. 整合薪资:")result=result.join(salary_info,how='left')print(result)# 3. 整合绩效print("\n3. 整合绩效:")result=result.join(performance_info,how='left')print(result)# 4. 链式整合print("\n4. 链式整合:")final=basic_info.join([dept_info,salary_info,performance_info],how='left')print(final)# 5. 统计print("\n5. 各部门平均工资:")dept_avg=final.groupby('部门')['工资'].mean().round(0)print(dept_avg)# 6. 缺失值分析print("\n6. 数据完整性:")print(f"总员工数:{len(final)}")print(f"有工资信息的员工:{final['工资'].notna().sum()}")print(f"有绩效信息的员工:{final['绩效'].notna().sum()}")
8. join vs merge 对比
| 特性 | join | merge |
|---|
| 默认连接键 | 索引 | 列 |
| 语法 | df1.join(df2) | pd.merge(df1, df2) |
| 多表连接 | df1.join([df2, df3]) | 需要多次调用 |
| 灵活性 | 较低 | 较高 |
| 适用场景 | 基于索引合并 | 基于列合并 |
9. 参数详解
| 参数 | 说明 | 默认值 |
|---|
other | 要连接的 DataFrame | 必填 |
on | 左表用于连接的列名 | None |
how | 连接方式 | 'left' |
lsuffix | 左表重复列后缀 | '' |
rsuffix | 右表重复列后缀 | '' |
sort | 是否按索引排序 | False |
10. 总结
| 需求 | 方法 | 示例 |
|---|
| 基于索引连接 | df1.join(df2) | df1.join(df2) |
| 左连接 | join(df2, how='left') | df1.join(df2, how='left') |
| 内连接 | join(df2, how='inner') | df1.join(df2, how='inner') |
| 多表连接 | join([df2, df3]) | df1.join([df2, df3]) |
| 处理重复列 | lsuffix='_左', rsuffix='_右' | df1.join(df2, lsuffix='_左', rsuffix='_右') |
| 使用列连接 | join(df2, on='key') | df1.join(df2, on='key') |