趋近智
提供使用 pd.concat、pd.merge 和 .join() 方法的实际操作示例。我们将使用小型、清晰的数据集来说明每种技术的工作方式。
首先,确保已导入 Pandas。我们将使用约定俗成的别名 pd。
import pandas as pd
import numpy as np # 通常与 Pandas 一起使用
为了演示连接和合并,我们来创建几个简单的 DataFrame。
# 用于连接的 DataFrame 示例
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2'],
'C': ['C0', 'C1', 'C2']},
index=[0, 1, 2])
df2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'],
'B': ['B3', 'B4', 'B5'],
'C': ['C3', 'C4', 'C5']},
index=[3, 4, 5])
df3 = pd.DataFrame({'D': ['D0', 'D1', 'D2'],
'E': ['E0', 'E1', 'E2'],
'F': ['F0', 'F1', 'F2']},
index=[0, 1, 2])
# 用于合并/连接的 DataFrame 示例
left_df = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
'L_val': ['L0', 'L1', 'L2', 'L3']})
right_df = pd.DataFrame({'key': ['K0', 'K1', 'K4', 'K5'],
'R_val': ['R0', 'R1', 'R4', 'R5']})
# 用于基于索引连接的 DataFrame 示例
left_join_df = pd.DataFrame({'L_val': ['L0', 'L1', 'L2']},
index=pd.Index(['K0', 'K1', 'K2'], name='key'))
right_join_df = pd.DataFrame({'R_val': ['R0', 'R1', 'R4']},
index=pd.Index(['K0', 'K1', 'K4'], name='key'))
我们来看看最初的 DataFrame:
print("--- df1 ---")
print(df1)
print("\n--- df2 ---")
print(df2)
print("\n--- df3 ---")
print(df3)
print("\n--- left_df ---")
print(left_df)
print("\n--- right_df ---")
print(right_df)
print("\n--- left_join_df ---")
print(left_join_df)
print("\n--- right_join_df ---")
print(right_join_df)
pd.concat 进行连接连接类似于将 DataFrame 堆叠或拼接在一起。
这是 pd.concat 的默认行为。它垂直堆叠 DataFrame,按名称对齐 (alignment)列。
# 垂直连接 df1 和 df2 (axis=0 是默认值)
vertical_concat = pd.concat([df1, df2])
print("--- 垂直连接(默认)---")
print(vertical_concat)
请注意 df2 是如何附加在 df1 下方的。原始 DataFrame 的索引被保留了。如果索引的唯一性很重要,或者你更喜欢一个整洁的从 0 开始的索引,请使用 ignore_index=True。
# 连接 df1 和 df2,忽略原始索引
vertical_concat_new_index = pd.concat([df1, df2], ignore_index=True)
print("\n--- 垂直连接 (ignore_index=True) ---")
print(vertical_concat_new_index)
要根据 DataFrame 的索引将它们并排放置,请使用 axis=1。
# 水平连接 df1 和 df3 (axis=1)
horizontal_concat = pd.concat([df1, df3], axis=1)
print("--- 水平连接 (axis=1) ---")
print(horizontal_concat)
这里,df1 和 df3 是根据匹配的索引标签(0, 1, 2)组合的。如果索引没有完美对齐,Pandas 将为缺失的匹配项引入 NaN 值(这是一种沿着索引的外连接行为)。
pd.merge 进行合并合并根据公共列中的值组合 DataFrame,类似于 SQL 连接。
内连接只保留键在两个 DataFrame 中都存在的行。
# 对列执行内连接
inner_merge = pd.merge(left_df, right_df, on='key', how='inner') # 'how=inner' 是默认值
print("--- 内连接 ---")
print(inner_merge)
只有同时存在于 left_df 和 right_df 中的键 'K0' 和 'K1' 出现在结果中。
外连接保留两个 DataFrame 中的所有行。如果一个键在其中一个 DataFrame 中不存在,则会为源自该 DataFrame 的列引入 NaN 值。
# 对列执行外连接
outer_merge = pd.merge(left_df, right_df, on='key', how='outer')
print("\n--- 外连接 ---")
print(outer_merge)
键 'K0'、'K1'、'K2'、'K3'、'K4' 和 'K5' 都存在。请注意,当键在其中一个原始 DataFrame 中缺失时(例如,'K2' 和 'K3' 的 R_val 为 NaN,'K4' 和 'K5' 的 L_val 为 NaN),会出现 NaN 值。
左连接保留左侧 DataFrame 中的所有行,并包含来自右侧 DataFrame 的匹配行。如果左侧 DataFrame 的键在右侧不存在,则右侧 DataFrame 的列将使用 NaN。
# 对列执行左连接
left_merge = pd.merge(left_df, right_df, on='key', how='left')
print("\n--- 左连接 ---")
print(left_merge)
left_df 中的所有键('K0'、'K1'、'K2'、'K3')都存在。'K2' 和 'K3' 的 R_val 为 NaN,因为它们不在 right_df 中。仅存在于 right_df 中的键('K4'、'K5')被排除。
右连接与左连接相反。它保留右侧 DataFrame 中的所有行,并包含来自左侧的匹配行。
# 对列执行右连接
right_merge = pd.merge(left_df, right_df, on='key', how='right')
print("\n--- 右连接 ---")
print(right_merge)
right_df 中的所有键('K0'、'K1'、'K4'、'K5')都存在。'K4' 和 'K5' 的 L_val 为 NaN。仅存在于 left_df 中的键('K2'、'K3')被排除。
为了帮助可视化这些连接,可以将键视为集合:
基于键 'K0'-'K5' 的不同连接类型的图示。蓝色实心圆表示每种连接类型的结果中包含的键,假设
left_df的键是 K0-K3,right_df的键是 K0, K1, K4, K5。
如果 DataFrame 中的列具有不同的名称,请使用 left_on 和 right_on。
# 临时重命名 right_df 中的 'key',用于演示
right_df_renamed = right_df.rename(columns={'key': 'common_key'})
print("\n--- right_df_renamed ---")
print(right_df_renamed)
# 使用 left_on 和 right_on 进行合并
merge_diff_names = pd.merge(left_df, right_df_renamed,
left_on='key', right_on='common_key',
how='inner')
print("\n--- 使用不同名称合并 (left_on, right_on) ---")
print(merge_diff_names)
结果中包含两个原始列(left_df 中的 key 和 right_df_renamed 中的 common_key)。之后你可能需要删除其中一个。
.join 进行基于索引的连接.join() 方法是一种基于 DataFrame 索引执行合并的便捷方式。它默认为左连接。
# 对索引执行默认(左)连接
left_index_join = left_join_df.join(right_join_df, how='left') # 'how=left' 是默认值
print("--- 左索引连接(默认 .join())---")
print(left_index_join)
这会保留 left_join_df 中的所有索引值('K0'、'K1'、'K2'),并添加来自 right_join_df 的相应 R_val。'K2' 的 R_val 为 NaN,因为它不在 right_join_df 的索引中。
你可以使用 how 参数 (parameter)指定其他连接类型,就像使用 pd.merge 一样。
# 使用 .join() 对索引执行外连接
outer_index_join = left_join_df.join(right_join_df, how='outer')
print("\n--- 外索引连接 (.join(how='outer')) ---")
print(outer_index_join)
这包含两个 DataFrame 的所有索引值('K0'、'K1'、'K2'、'K4'),并用 NaN 填充缺失值。
你还可以使用 .join() 将 DataFrame 的索引与另一个 DataFrame 中的列进行连接,方法是将连接列临时设置为另一个 DataFrame 的索引,或者使用 .join() 中的 on 参数。
# 将 left_df(使用列)与 right_join_df(使用其索引)连接
# 我们可以在 join 中使用 'on' 参数来指定 left_df 中的列
column_index_join = left_df.join(right_join_df, on='key', how='inner')
print("\n--- 将列连接到索引 (right_join_df) ---")
print(column_index_join)
本次实践涵盖了在 Pandas 中组合 DataFrame 的主要方法。连接是堆叠数据,而合并和连接是根据共享键(在列或索引中)使用不同的逻辑规则(内、外、左、右)组合数据。请在你自己的数据集上试验这些技术,以巩固你的理解。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•