Pandas中合并DataFrame主要用pd.merge()和pd.concat(),前者基于键进行类似SQL的连接操作,后者按行或列堆叠数据。merge()适用于有共同键的逻辑关联数据,支持inner、left、right、outer等连接方式;concat()用于结构相似的数据拼接,默认按行堆叠,可设置join='inner'保留公共部分。常见陷阱包括键类型不一致、列名不同、索引重复及NaN处理问题。此外,.join()方法适合基于索引的合并,map()可用于高效添加单列信息。选择合适方法需根据数据结构与整合目标决定。

在Python中,合并两个Pandas DataFrame的核心方法主要围绕
pd.merge()
pd.concat()
合并Pandas DataFrame,我们通常会根据数据的结构和我们想要达成的目标来选择
merge()
concat()
pd.merge()
举个例子,假设我们有两个DataFrame,一个包含用户信息,另一个包含用户的订单信息:
立即学习“Python免费学习笔记(深入)”;
import pandas as pd
# 用户信息
df_users = pd.DataFrame({
'user_id': [1, 2, 3, 4],
'name': ['Alice', 'Bob', 'Charlie', 'David'],
'city': ['New York', 'London', 'Paris', 'Tokyo']
})
# 订单信息
df_orders = pd.DataFrame({
'order_id': [101, 102, 103, 104, 105],
'user_id': [1, 2, 1, 3, 5], # 注意user_id 5 不在df_users中
'product': ['Laptop', 'Mouse', 'Keyboard', 'Monitor', 'Webcam'],
'price': [1200, 25, 75, 300, 50]
})
print("df_users:")
print(df_users)
print("\ndf_orders:")
print(df_orders)使用pd.merge()
最常见的合并类型是内连接(inner join),它只保留两个DataFrame中键都存在的行。
# 内连接:只保留两个DataFrame中user_id都存在的行
merged_inner = pd.merge(df_users, df_orders, on='user_id', how='inner')
print("\nInner Join (merged_inner):")
print(merged_inner)如果我们需要保留所有用户信息,即使他们没有订单,那就需要左连接(left join):
# 左连接:保留左边DataFrame的所有行,匹配右边DataFrame的行
merged_left = pd.merge(df_users, df_orders, on='user_id', how='left')
print("\nLeft Join (merged_left):")
print(merged_left)反过来,如果想保留所有订单信息,即使对应的用户不在用户信息表中,就是右连接(right join):
# 右连接:保留右边DataFrame的所有行,匹配左边DataFrame的行
merged_right = pd.merge(df_users, df_orders, on='user_id', how='right')
print("\nRight Join (merged_right):")
print(merged_right)当然,还有外连接(outer join),它会保留两个DataFrame中的所有行,不匹配的地方用NaN填充:
# 外连接:保留两个DataFrame的所有行
merged_outer = pd.merge(df_users, df_orders, on='user_id', how='outer')
print("\nOuter Join (merged_outer):")
print(merged_outer)使用pd.concat()
pd.concat()
假设我们有两部分用户数据:
df_users_part1 = pd.DataFrame({
'user_id': [1, 2],
'name': ['Alice', 'Bob']
})
df_users_part2 = pd.DataFrame({
'user_id': [3, 4],
'name': ['Charlie', 'David']
})
print("\ndf_users_part1:")
print(df_users_part1)
print("\ndf_users_part2:")
print(df_users_part2)
# 按行合并 (堆叠)
concatenated_rows = pd.concat([df_users_part1, df_users_part2])
print("\nConcatenated by rows:")
print(concatenated_rows)如果两个DataFrame的行索引或列索引不完全匹配,
concat
join='inner'
# 假设df_users_part1有额外列
df_users_part1_ext = pd.DataFrame({
'user_id': [1, 2],
'name': ['Alice', 'Bob'],
'email': ['alice@example.com', 'bob@example.com']
})
df_users_part2_simple = pd.DataFrame({
'user_id': [3, 4],
'name': ['Charlie', 'David']
})
# 默认join='outer'
concatenated_mixed_cols = pd.concat([df_users_part1_ext, df_users_part2_simple])
print("\nConcatenated with mixed columns (default outer join):")
print(concatenated_mixed_cols)
# 只保留共同的列
concatenated_inner_cols = pd.concat([df_users_part1_ext, df_users_part2_simple], join='inner')
print("\nConcatenated with inner join on columns:")
print(concatenated_inner_cols)merge()
concat()
在我看来,
merge()
concat()
merge()
concat()
merge()
merge()
inner
left
right
outer
left
inner
而
concat()
concat()
axis=0
axis=1
merge()
简而言之,当你的数据之间存在明确的“一对一”、“一对多”或“多对多”的逻辑关系,需要通过共同的标识符来关联时,用
merge()
concat()
在实际操作中,合并DataFrame确实有一些坑,我个人就踩过不少。理解这些常见问题能帮我们省下很多调试时间。
一个非常常见的陷阱是键列的数据类型不一致。比如说,一个DataFrame的
user_id
user_id
'1'
'2'
merge()
df['column'].dtype
df['column'].astype(str)
astype(int)
另一个坑是键列名不一致。比如一个表是
user_id
UserID
merge()
left_on
right_on
on
索引问题也是
concat()
concat()
ignore_index=True
此外,处理缺失值(NaN)也是一个需要注意的地方。特别是使用
left
right
outer
最后,性能问题在大数据集合并时也不容忽视。如果你的DataFrame非常大,不恰当的合并操作可能会消耗大量内存和计算时间。例如,在没有必要的情况下使用
outer
merge()
concat()
确实,
merge()
concat()
一个非常实用的替代方案是DataFrame对象的.join()
pd.merge()
例如,如果我们想把订单信息
df_orders
df_users
user_id
df_users
user_id
# 将df_users的user_id设置为索引
df_users_indexed = df_users.set_index('user_id')
print("\ndf_users_indexed:")
print(df_users_indexed)
# 使用join方法,df_orders的user_id列与df_users_indexed的索引进行匹配
# left_on指定左边DataFrame的列,right_index=True表示右边DataFrame用索引
joined_df = df_orders.join(df_users_indexed, on='user_id', how='left')
print("\nJoined using .join() method:")
print(joined_df).join()
how='left'
join()
merge()
另一个值得一提的策略是pd.Series.map()
pd.DataFrame.apply()
例如,我们想根据
df_orders
user_id
df_users
name
city
# 创建一个user_id到name的映射字典
user_name_map = df_users.set_index('user_id')['name'].to_dict()
user_city_map = df_users.set_index('user_id')['city'].to_dict()
# 使用map方法将name和city添加到df_orders
df_orders_with_details = df_orders.copy()
df_orders_with_details['user_name'] = df_orders_with_details['user_id'].map(user_name_map)
df_orders_with_details['user_city'] = df_orders_with_details['user_id'].map(user_city_map)
print("\nOrders with user details added via .map():")
print(df_orders_with_details)这种方式的优点是,它不会像
merge()
最后,对于一些非常规的、需要高度自定义的合并逻辑,我们有时会退而求其次,手动迭代或使用apply()
merge()
concat()
join()
总的来说,理解这些不同的策略,并根据具体的数据结构和业务需求灵活选择,是成为一个高效Pandas用户的重要一步。
以上就是Python怎么合并两个DataFrame_pandas DataFrame数据合并技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号