
本教程将指导您如何在pandas中高效地执行两个dataframe的笛卡尔积(交叉连接)操作。我们将通过添加辅助合并键并利用`pd.merge`函数,避免低效的循环,快速生成所有可能的行组合,从而实现数据表的全面扩展与整合,尤其适用于大规模数据集。
在数据处理中,我们有时需要将两个或多个数据集中的所有记录进行两两组合,形成一个包含所有可能组合的新数据集。这种操作在关系型数据库中被称为“交叉连接”(Cross Join),在数学上则称为“笛卡尔积”(Cartesian Product)。例如,如果您有一个包含日期列表的DataFrame df_1,以及一个包含人员信息的DataFrame df_2,您可能希望创建一个新DataFrame,其中包含每个日期与每个人员信息的所有组合。
考虑以下两个示例DataFrame:
df_1:
A1 0 2023-12-30 1 2023-12-31
df_2:
B1 B2 B3 501 Sam 159cm 300gm 502 Tam 175cm 400gm
我们期望的输出结果 df_result 应该将 df_1 中的每个日期与 df_2 中的每个人员信息进行组合,如下所示:
df_result:
A1 B1 B2 B3 0 2023-12-30 Sam 159cm 300gm 1 2023-12-31 Sam 159cm 300gm 2 2023-12-30 Tam 175cm 300gm 3 2023-12-31 Tam 175cm 400gm
尽管使用 for 循环可以实现这一目标,但对于大型DataFrame来说,这种方法效率极低,会导致显著的性能问题。因此,我们需要一种更“Pythonic”和“Pandas”化的解决方案。
Pandas库提供了强大的合并(merge)功能,通过巧妙地利用这一功能,我们可以高效地实现笛卡尔积。核心思想是为两个DataFrame添加一个共同的、具有相同常数值的辅助列,然后基于这个辅助列进行内连接(inner merge)。
首先,我们创建上述示例中提到的两个DataFrame:
import pandas as pd
# DataFrame 1
data_1 = {'A1': ['2023-12-30', '2023-12-31']}
df_1 = pd.DataFrame(data_1)
# DataFrame 2
data_2 = {'B1': ['Sam', 'Tam'],
'B2': ['159cm', '175cm'],
'B3': ['300gm', '400gm']}
df_2 = pd.DataFrame(data_2, index=[501, 502]) # 保持原始索引,但实际合并中索引不重要
print("df_1:")
print(df_1)
print("\ndf_2:")
print(df_2)为了执行笛卡尔积,我们需要在两个DataFrame中都添加一个具有相同常数值的临时列。这个列将作为我们合并操作的键。
# 为df_1添加一个名为'key'的辅助列,所有值为1
df_1['key'] = 1
# 为df_2添加一个名为'key'的辅助列,所有值为1
df_2['key'] = 1
print("\ndf_1 with key:")
print(df_1)
print("\ndf_2 with key:")
print(df_2)此时,df_1和df_2看起来会是这样:
df_1 with key:
A1 key 0 2023-12-30 1 1 2023-12-31 1
df_2 with key:
B1 B2 B3 key 501 Sam 159cm 300gm 1 502 Tam 175cm 400gm 1
现在,我们可以使用 pd.merge() 函数,指定 on='key' 和 how='inner' 来执行合并操作。由于两个DataFrame中的所有行都共享相同的 key 值(即 1),pd.merge 会将 df_1 中的每一行与 df_2 中的每一行进行匹配,从而生成笛卡尔积。
# 执行内部合并
df_result = pd.merge(df_1, df_2, on='key', how='inner')
print("\nMerged DataFrame (before dropping key):")
print(df_result)合并后的结果会包含辅助列 key:
Merged DataFrame (before dropping key):
A1 key B1 B2 B3 0 2023-12-30 1 Sam 159cm 300gm 1 2023-12-30 1 Tam 175cm 400gm 2 2023-12-31 1 Sam 159cm 300gm 3 2023-12-31 1 Tam 175cm 400gm
请注意,这里的行顺序可能与示例输出略有不同,但所有组合都已生成。Pandas合并的默认行为是保留左侧DataFrame的顺序,然后按右侧DataFrame的匹配顺序。
最后一步是移除不再需要的辅助列 key,以获得最终的笛卡尔积结果。
# 移除辅助列'key'
df_result = df_result.drop('key', axis=1)
print("\nFinal df_result (Cartesian Product):")
print(df_result)最终的 df_result 将与我们期望的输出完全一致。
以下是实现两个DataFrame笛卡尔积的完整、简洁的代码:
import pandas as pd
# 1. 准备示例数据
df_1 = pd.DataFrame({'A1': ['2023-12-30', '2023-12-31']})
df_2 = pd.DataFrame({'B1': ['Sam', 'Tam'],
'B2': ['159cm', '175cm'],
'B3': ['300gm', '400gm']})
print("df_1:")
print(df_1)
print("\ndf_2:")
print(df_2)
# 2. 添加辅助合并键并执行内部合并,然后清理
df_result = pd.merge(df_1.assign(key=1),
df_2.assign(key=1),
on='key',
how='inner').drop('key', axis=1)
print("\nFinal df_result (Cartesian Product):")
print(df_result)这种方法的有效性在于 pd.merge 函数在执行 inner 合并时的行为。当两个DataFrame都含有一个名为 key 且所有值都为 1 的列时,pd.merge 会尝试将 df_1 中 key 值为 1 的每一行,与 df_2 中 key 值为 1 的每一行进行匹配。由于所有的行都满足 key == 1 的条件,因此 df_1 的每一行都会与 df_2 的每一行进行组合,从而完美地实现了笛卡尔积。
通过为两个DataFrame添加一个具有相同常数值的辅助列,并利用 pd.merge 进行内连接,我们可以高效、简洁地实现两个DataFrame的笛卡尔积。这种方法避免了低效的循环,是处理大规模数据集时进行全面组合的强大工具。理解其背后的原理和潜在的内存消耗,将帮助您更有效地利用Pandas进行数据处理。
以上就是Pandas中高效实现两个DataFrame的笛卡尔积(交叉连接)的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号