文章目录
- concat()是最基础的数据合并方法,默认沿轴0(行方向)合并: import pandas as pd # 创建示例DataFrame df1 = pd.DataFrame({‘A’: [‘A0’, ‘A1’], ‘B’: [‘B0’, ‘B1’]}) df2 = pd.DataFrame({‘A’: [‘A2’, ‘A3’], ‘B’: [‘B2’, ‘B3’]}) # 纵向合并(堆叠) result = pd.concat([df1, df2], axis=0) print(result)
- 设置axis=1可实现横向合并: df3 = pd.DataFrame({‘C’: [‘C0’, ‘C1’]}) df4 = pd.DataFrame({‘D’: [‘D0’, ‘D1’]}) # 横向合并 result = pd.concat([df3, df4], axis=1) print(result)
- 合并后常出现重复索引,可通过以下参数控制: # 忽略原索引,创建新数字索引 result = pd.concat([df1, df2], ignore_index=True) # 保留原索引并添加多级索引 result = pd.concat([df1, df2], keys=[‘df1’, ‘df2’]) print(result)
- merge()是Pandas中最强大的连接方法,类似于SQL中的JOIN操作: # 创建示例DataFrame left = pd.DataFrame({‘key’: [‘K0’, ‘K1’, ‘K2’], ‘A’: [‘A0’, ‘A1’, ‘A2’]}) right = pd.DataFrame({‘key’: [‘K0’, ‘K1’, ‘K3’], ‘B’: [‘B0’, ‘B1’, ‘B2′]}) # 内连接(默认) result = pd.merge(left, right, on=’key’) print(result)
- Pandas支持所有标准SQL连接类型: # 左连接(保留左表所有记录) left_join = pd.merge(left, right, on=’key’, how=’left’) # 右连接(保留右表所有记录) right_join = pd.merge(left, right, on=’key’, how=’right’) # 外连接(保留所有记录) outer_join = pd.merge(left, right, on=’key’, how=’outer’)
- 可以基于多个列进行连接: left_multi = pd.DataFrame({ ‘key1’: [‘K0’, ‘K0’, ‘K1’], ‘key2’: [‘K0’, ‘K1’, ‘K0’], ‘A’: [‘A0’, ‘A1’, ‘A2’] }) right_multi = pd.DataFrame({ ‘key1’: [‘K0’, ‘K1’], ‘key2’: [‘K0’, ‘K0’], ‘B’: [‘B0’, ‘B1’] }) result = pd.merge(left_multi, right_multi, on=[‘key1’, ‘key2’])
- 当连接列名相同时,Pandas会自动添加后缀: # 自定义后缀 result = pd.merge(left, right, on=’key’, suffixes=(‘_left’, ‘_right’))
- join()是merge()的简化版,专门用于基于索引的连接: # 创建示例DataFrame df1 = pd.DataFrame({‘A’: [‘A0’, ‘A1’]}, index=[‘K0’, ‘K1’]) df2 = pd.DataFrame({‘B’: [‘B0’, ‘B1’]}, index=[‘K0’, ‘K2′]) # 左连接(默认) result = df1.join(df2, how=’left’) print(result)
- 可以一次性连接多个DataFrame: df3 = pd.DataFrame({‘C’: [‘C0’, ‘C1’]}, index=[‘K0’, ‘K2′]) result = df1.join([df2, df3], how=’outer’)
- 可以添加一列显示记录来源: result = pd.merge(left, right, on=’key’, how=’outer’, indicator=True) print(result)
- Pandas会自动对齐数据类型,但有时需要手动转换: left[‘key’] = left[‘key’].astype(str) # 转换为字符串类型 right[‘key’] = right[‘key’].astype(str) result = pd.merge(left, right, on=’key’)
- 使用update()方法用右表更新左表中的值: df1 = pd.DataFrame({‘A’: [1, 2], ‘B’: [3, 4]}) df2 = pd.DataFrame({‘A’: [5, 6]}, index=[0, 1]) df1.update(df2) # 只更新匹配的行和列 print(df1)
- 可以在合并时对重叠列应用函数: from pandas.api.types import CategoricalDtype # 自定义合并函数 def merge_with_func(left, right): return left + ‘_’ + right # 示例:字符串连接 # 创建示例 df1 = pd.DataFrame({‘key’: [‘K0’, ‘K1’], ‘val’: [‘A’, ‘B’]}) df2 = pd.DataFrame({‘key’: [‘K0’, ‘K1’], ‘val’: [‘1’, ‘2’]}) # 先合并再应用函数(实际中可能需要更复杂的处理) result = pd.merge(df1, df2, on=’key’) result[‘combined’] = result[‘val_x’] + ‘_’ + result[‘val_y’]
- 对于低基数列,转换为category类型可以提高合并速度: df1[‘key’] = df1[‘key’].astype(‘category’) df2[‘key’] = df2[‘key’].astype(‘category’)
- 对连接键预先排序可以显著提高大数据集的合并速度: df1 = df1.sort_values(‘key’) df2 = df2.sort_values(‘key’)
- 对于超出内存的数据集,可以使用Dask库: import dask.dataframe as dd ddf1 = dd.from_pandas(df1, npartitions=2) ddf2 = dd.from_pandas(df2, npartitions=2) result = dd.merge(ddf1, ddf2, on=’key’).compute()
- # 订单数据 orders = pd.DataFrame({ ‘order_id’: [1, 2, 3], ‘customer_id’: [101, 102, 103], ‘amount’: [100, 200, 150] }) # 客户数据 customers = pd.DataFrame({ ‘customer_id’: [101, 102, 104], ‘name’: [‘Alice’, ‘Bob’, ‘Charlie’], ‘segment’: [‘A’, ‘B’, ‘C’] }) # 左连接获取完整订单信息(包括未匹配的客户) order_details = pd.merge( orders, customers, on=’customer_id’, how=’left’ ) print(order_details)
- # 创建两个时间序列数据集(时间不完全对齐) dates1 = pd.date_range(‘2023-01-01’, periods=5) dates2 = pd.date_range(‘2023-01-03’, periods=5) df_temp = pd.DataFrame({‘date’: dates1, ‘temp’: [20, 21, 22, 23, 24]}) df_rain = pd.DataFrame({‘date’: dates2, ‘rain’: [0.1, 0.2, 0.0, 0.3, 0.1]}) # 外连接并对齐日期 weather_data = pd.merge( df_temp, df_rain, on=’date’, how=’outer’ ).sort_values(‘date’) print(weather_data)
- # 员工基本信息 employees = pd.DataFrame({ ’emp_id’: [1, 2, 3], ‘name’: [‘Alice’, ‘Bob’, ‘Charlie’], ‘dept’: [‘HR’, ‘IT’, ‘Finance’] }) # 薪资数据 salaries = pd.DataFrame({ ’emp_id’: [1, 2, 4], # 注意有员工4不在基本信息中 ‘salary’: [50000, 80000, 70000] }) # 部门信息 departments = pd.DataFrame({ ‘dept’: [‘HR’, ‘IT’, ‘Finance’], ‘location’: [‘Building A’, ‘Building B’, ‘Building C’] }) # 多步合并:先合并员工和薪资,再合并部门信息 step1 = pd.merge(employees, salaries, on=’emp_id’, how=’outer’) result = pd.merge(step1, departments, on=’dept’, how=’left’) print(result)
- # 使用suffixes参数处理 result = pd.merge(df1, df2, on=’key’, suffixes=(‘_left’, ‘_right’))
- 检查连接类型是否正确: # 确认连接类型 print(f”左表行数: {len(left)}”) print(f”右表行数: {len(right)}”) print(f”内连接结果: {len(pd.merge(left, right, on=’key’, how=’inner’))}”)
- # 检查并转换数据类型 print(left[‘key’].dtype) print(right[‘key’].dtype) # 统一转换为字符串 left[‘key’] = left[‘key’].astype(str) right[‘key’] = right[‘key’].astype(str)
- # 分块处理大型合并 chunk_size = 100000 results = [] for i in range(0, len(df1), chunk_size): chunk = pd.merge( df1.iloc[i:i+chunk_size], df2, on=’key’ ) results.append(chunk) final_result = pd.concat(results, ignore_index=True)
目录
- 引言
- 一、合并基础:concat()方法
- 1.1 基本纵向合并(堆叠)
- 1.2 基本横向合并(并排)
- 1.3 处理索引问题
- 二、数据库风格的连接:merge()方法
- 2.1 基本内连接(INNER JOIN)
- 2.2 不同连接类型
- 2.3 多键连接
- 2.4 处理列名冲突
- 三、基于索引的连接:join()方法
- 3.1 基本索引连接
- 3.2 多DataFrame连接
- 四、高级合并技巧
- 4.1 合并时添加指示器列
- 4.2 合并不同数据类型
- 4.3 合并时更新值
- 4.4 合并时应用函数
- 五、性能优化技巧
- 5.1 使用category类型优化合并
- 5.2 预先排序提高合并效率
- 5.3 使用Dask处理超大数据集
- 六、实际应用案例
- 案例1:整合销售数据
- 案例2:时间序列数据对齐
- 案例3:多源数据整合
- 七、常见问题解决
- 问题1:合并后出现重复列
- 问题2:合并后数据量异常
- 问题3:合并时数据类型不匹配
- 问题4:处理大型合并时的内存问题
- 总结
在数据分析工作中,我们经常需要处理来自多个来源的数据。将这些分散的数据集整合成一个统一的结构是分析前的关键步骤。Pandas库提供了多种强大的数据合并与连接方法,能够高效处理各种数据整合场景。本文将系统介绍Pandas中DataFrame合并与连接的核心技术,帮助你掌握数据整合的艺术。
concat()是最基础的数据合并方法,默认沿轴0(行方向)合并:
import pandas as pd
# 创建示例DataFrame
df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
# 纵向合并(堆叠)
result = pd.concat([df1, df2], axis=0)
print(result)
设置axis=1可实现横向合并:
df3 = pd.DataFrame({'C': ['C0', 'C1']})
df4 = pd.DataFrame({'D': ['D0', 'D1']})
# 横向合并
result = pd.concat([df3, df4], axis=1)
print(result)
合并后常出现重复索引,可通过以下参数控制:
# 忽略原索引,创建新数字索引 result = pd.concat([df1, df2], ignore_index=True) # 保留原索引并添加多级索引 result = pd.concat([df1, df2], keys=['df1', 'df2']) print(result)
merge()是Pandas中最强大的连接方法,类似于SQL中的JOIN操作:
# 创建示例DataFrame
left = pd.DataFrame({'key': ['K0', 'K1', 'K2'], 'A': ['A0', 'A1', 'A2']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K3'], 'B': ['B0', 'B1', 'B2']})
# 内连接(默认)
result = pd.merge(left, right, on='key')
print(result)
Pandas支持所有标准SQL连接类型:
# 左连接(保留左表所有记录) left_join = pd.merge(left, right, on='key', how='left') # 右连接(保留右表所有记录) right_join = pd.merge(left, right, on='key', how='right') # 外连接(保留所有记录) outer_join = pd.merge(left, right, on='key', how='outer')
可以基于多个列进行连接:
left_multi = pd.DataFrame({
'key1': ['K0', 'K0', 'K1'],
'key2': ['K0', 'K1', 'K0'],
'A': ['A0', 'A1', 'A2']
})
right_multi = pd.DataFrame({
'key1': ['K0', 'K1'],
'key2': ['K0', 'K0'],
'B': ['B0', 'B1']
})
result = pd.merge(left_multi, right_multi, on=['key1', 'key2'])
当连接列名相同时,Pandas会自动添加后缀:
# 自定义后缀
result = pd.merge(left, right, on='key', suffixes=('_left', '_right'))
join()是merge()的简化版,专门用于基于索引的连接:
# 创建示例DataFrame
df1 = pd.DataFrame({'A': ['A0', 'A1']}, index=['K0', 'K1'])
df2 = pd.DataFrame({'B': ['B0', 'B1']}, index=['K0', 'K2'])
# 左连接(默认)
result = df1.join(df2, how='left')
print(result)
可以一次性连接多个DataFrame:
df3 = pd.DataFrame({'C': ['C0', 'C1']}, index=['K0', 'K2'])
result = df1.join([df2, df3], how='outer')
可以添加一列显示记录来源:
result = pd.merge(left, right, on='key', how='outer', indicator=True) print(result)
Pandas会自动对齐数据类型,但有时需要手动转换:
left['key'] = left['key'].astype(str) # 转换为字符串类型 right['key'] = right['key'].astype(str) result = pd.merge(left, right, on='key')
使用update()方法用右表更新左表中的值:
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6]}, index=[0, 1])
df1.update(df2) # 只更新匹配的行和列
print(df1)
可以在合并时对重叠列应用函数:
from pandas.api.types import CategoricalDtype
# 自定义合并函数
def merge_with_func(left, right):
return left + '_' + right # 示例:字符串连接
# 创建示例
df1 = pd.DataFrame({'key': ['K0', 'K1'], 'val': ['A', 'B']})
df2 = pd.DataFrame({'key': ['K0', 'K1'], 'val': ['1', '2']})
# 先合并再应用函数(实际中可能需要更复杂的处理)
result = pd.merge(df1, df2, on='key')
result['combined'] = result['val_x'] + '_' + result['val_y']
对于低基数列,转换为category类型可以提高合并速度:
df1['key'] = df1['key'].astype('category')
df2['key'] = df2['key'].astype('category')
对连接键预先排序可以显著提高大数据集的合并速度:
df1 = df1.sort_values('key')
df2 = df2.sort_values('key')
对于超出内存的数据集,可以使用Dask库:
import dask.dataframe as dd ddf1 = dd.from_pandas(df1, npartitions=2) ddf2 = dd.from_pandas(df2, npartitions=2) result = dd.merge(ddf1, ddf2, on='key').compute()
# 订单数据
orders = pd.DataFrame({
'order_id': [1, 2, 3],
'customer_id': [101, 102, 103],
'amount': [100, 200, 150]
})
# 客户数据
customers = pd.DataFrame({
'customer_id': [101, 102, 104],
'name': ['Alice', 'Bob', 'Charlie'],
'segment': ['A', 'B', 'C']
})
# 左连接获取完整订单信息(包括未匹配的客户)
order_details = pd.merge(
orders,
customers,
on='customer_id',
how='left'
)
print(order_details)
# 创建两个时间序列数据集(时间不完全对齐)
dates1 = pd.date_range('2023-01-01', periods=5)
dates2 = pd.date_range('2023-01-03', periods=5)
df_temp = pd.DataFrame({'date': dates1, 'temp': [20, 21, 22, 23, 24]})
df_rain = pd.DataFrame({'date': dates2, 'rain': [0.1, 0.2, 0.0, 0.3, 0.1]})
# 外连接并对齐日期
weather_data = pd.merge(
df_temp,
df_rain,
on='date',
how='outer'
).sort_values('date')
print(weather_data)
# 员工基本信息
employees = pd.DataFrame({
'emp_id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie'],
'dept': ['HR', 'IT', 'Finance']
})
# 薪资数据
salaries = pd.DataFrame({
'emp_id': [1, 2, 4], # 注意有员工4不在基本信息中
'salary': [50000, 80000, 70000]
})
# 部门信息
departments = pd.DataFrame({
'dept': ['HR', 'IT', 'Finance'],
'location': ['Building A', 'Building B', 'Building C']
})
# 多步合并:先合并员工和薪资,再合并部门信息
step1 = pd.merge(employees, salaries, on='emp_id', how='outer')
result = pd.merge(step1, departments, on='dept', how='left')
print(result)
# 使用suffixes参数处理
result = pd.merge(df1, df2, on='key', suffixes=('_left', '_right'))
检查连接类型是否正确:
# 确认连接类型
print(f"左表行数: {len(left)}")
print(f"右表行数: {len(right)}")
print(f"内连接结果: {len(pd.merge(left, right, on='key', how='inner'))}")
# 检查并转换数据类型
print(left['key'].dtype)
print(right['key'].dtype)
# 统一转换为字符串
left['key'] = left['key'].astype(str)
right['key'] = right['key'].astype(str)
# 分块处理大型合并
chunk_size = 100000
results = []
for i in range(0, len(df1), chunk_size):
chunk = pd.merge(
df1.iloc[i:i+chunk_size],
df2,
on='key'
)
results.append(chunk)
final_result = pd.concat(results, ignore_index=True)
DataFrame的合并与连接是数据分析中不可或缺的技能,掌握它们可以让你:
- 高效整合来自不同来源的数据
- 构建适合分析的完整数据集
- 处理数据对齐和匹配问题
- 优化大数据集的处理性能
本文介绍了从基础到高级的合并连接技术,包括concat()、merge()和join()等核心方法,以及各种实际应用场景和性能优化技巧。记住,选择哪种合并方法取决于你的具体需求:
- 需要简单堆叠数据?使用
concat() - 需要基于键的复杂连接?使用
merge() - 需要基于索引的快速连接?使用
join()
通过实践这些技术,你将能够轻松应对各种数据整合挑战,为后续的数据分析和可视化奠定坚实基础。
以上就是Pandas DataFrame数据合并与连接的完整指南的详细内容,更多关于Pandas DataFrame数据合并与连接的资料请关注风君子博客其它相关文章!
您可能感兴趣的文章:
- pandas中DataFrame数据合并连接(merge、join、concat)
- 在Pandas中DataFrame数据合并,连接(concat,merge,join)的实例
- Pandas中DataFrame进行数据处理的完整指南
- Pandas DataFrame进行数据拼接方法详解