You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas实现多表合并,达到类数据库Join效果

如何用Pandas实现多表Join得到完整数据集?

问题描述

需要合并3个数据表(两个业务信息表+一个中间关联表),最终得到包含userId, bookId, likes, title, author, Location, Age的数据集,实现类似SQL的Join效果。

相关列定义:

import pandas as pd

r_names = ['userId', 'bookId', 'likes']
cols1 = ['userId', 'bookId', 'likes']

u_names = ['userId', 'Location', 'Age']
cols2 = ['userId', 'Location', 'Age']

b_names = ['bookId','title', 'author']
cols3 = ['bookId','title', 'author']

读取文件代码:

df1 = pd.read_csv('Ratings.csv', header=None, encoding="ISO-8859-1", names=r_names, usecols=cols1, index_col='userId')
df2 = pd.read_csv('Users.csv', header=None, encoding="ISO-8859-1", names=u_names, usecols=cols2, index_col='userId')
df3 = pd.read_csv('Books.csv', header=None, encoding="ISO-8859-1", names=b_names, usecols=cols3, index_col='bookId')

当前合并代码导致信息不完整:

df4 = pd.merge(df1, df2, how='outer', on=['userId'])
df5 = pd.merge(df3, df4, how='outer', on=['bookId'])

df5.to_csv('dataset', sep='\t', encoding='utf-8')
result = df5.head(10)
print("First 10 rows of the DataFrame:")
print(result)

问题原因

当前合并失败的核心问题是:读取文件时设置了index_col,导致关联键(userId/bookId)成为DataFrame的索引,而pd.merge默认仅使用普通列进行关联,不会自动识别索引列。此外,outer join会保留所有表的所有行,可能引入大量空值,若业务不需要全量数据,会造成"信息不完整"的错觉。

正确实现方案

方案1:读取时不设置索引,用普通列关联(推荐)

这是最直观的方式,让关联键作为普通列存在,避免索引带来的关联问题:

import pandas as pd

# 读取文件时不指定index_col,关联键保留为普通列
df1 = pd.read_csv('Ratings.csv', header=None, encoding="ISO-8859-1", names=r_names, usecols=cols1)
df2 = pd.read_csv('Users.csv', header=None, encoding="ISO-8859-1", names=u_names, usecols=cols2)
df3 = pd.read_csv('Books.csv', header=None, encoding="ISO-8859-1", names=b_names, usecols=cols3)

# 分步合并:先关联用户表与评分表(userId),再关联书籍表(bookId)
# 根据业务需求选择join类型:inner保留有效关联数据,outer保留全量数据
merged_df = pd.merge(df1, df2, on='userId', how='inner')
merged_df = pd.merge(merged_df, df3, on='bookId', how='inner')

# 调整列顺序为预期格式
desired_cols = ['userId', 'bookId', 'likes', 'title', 'author', 'Location', 'Age']
merged_df = merged_df[desired_cols]

# 输出结果
merged_df.to_csv('dataset.tsv', sep='\t', encoding='utf-8', index=False)
print("First 10 rows of merged DataFrame:")
print(merged_df.head(10))

方案2:保留索引时显式指定索引关联

若因其他需求必须设置index_col,可在合并时明确指定使用索引进行关联:

import pandas as pd

# 保留索引的读取方式
df1 = pd.read_csv('Ratings.csv', header=None, encoding="ISO-8859-1", names=r_names, usecols=cols1, index_col='userId')
df2 = pd.read_csv('Users.csv', header=None, encoding="ISO-8859-1", names=u_names, usecols=cols2, index_col='userId')
df3 = pd.read_csv('Books.csv', header=None, encoding="ISO-8859-1", names=b_names, usecols=cols3, index_col='bookId')

# 合并用户表与评分表:使用双方的userId索引
user_rating_merge = pd.merge(df1, df2, left_index=True, right_index=True, how='inner')
# 重置索引将userId转回普通列,再与书籍表的bookId索引关联
merged_df = pd.merge(user_rating_merge.reset_index(), df3.reset_index(), on='bookId', how='inner')

# 调整列顺序
desired_cols = ['userId', 'bookId', 'likes', 'title', 'author', 'Location', 'Age']
merged_df = merged_df[desired_cols]

# 输出结果
merged_df.to_csv('dataset.tsv', sep='\t', encoding='utf-8', index=False)
print(merged_df.head(10))

关键注意事项

  • 关联键的存在形式:pd.merge默认仅识别普通列,若关联键是索引,需显式设置left_index=True或right_index=True。
  • Join类型选择:
    • how='inner':仅保留三个表中存在有效关联的行,无冗余空值,适合多数业务场景。
    • how='outer':保留所有表的所有行,会引入大量空值,仅在需要全量数据时使用。
  • 列顺序控制:通过指定列列表可确保输出数据集的列顺序完全符合预期。

内容的提问来源于stack exchange,提问作者snloD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:17:04