
本教程详细介绍了如何使用Pandas和NumPy高效地比较两个DataFrame。我们将学习如何判断DataFrame A中的每一行,其各列值是否都能在DataFrame B的对应列中找到,并据此为DataFrame A添加一个新列,根据匹配结果赋值为“Open”或“New”。
1. 引言
在数据分析和处理过程中,我们经常需要对比两个数据集,并根据对比结果更新或生成新的数据。pandas库提供了强大的工具来处理这类任务。本文将聚焦于一个具体场景:比较两个dataframe,判断第一个dataframe中的行数据是否在第二个dataframe中“存在”(具体定义为:该行的每个元素是否在其对应列中存在于第二个dataframe),并根据此结果为第一个dataframe添加一个新列进行标记。
2. 问题描述与示例数据
假设我们有两个DataFrame,df1 和 df2。我们的目标是为 df1 添加一个名为 new_col 的新列。如果 df1 中的某一行,其所有列的值都能在 df2 的对应列中找到,则 new_col 的值为 “Open”;否则,为 “New”。
为了演示,我们创建以下示例数据:
import pandas as pdimport numpy as np# DataFrame A (df1)data1 = { 'A': [1, 2, 3, 4, 5], 'B': ['apple', 'banana', 'orange', 'apple', 'grape'], 'C': [10, 20, 30, 40, 50]}df1 = pd.DataFrame(data1)print("原始 DataFrame df1:")print(df1)# DataFrame B (df2)data2 = { 'A': [1, 2, 6], 'B': ['apple', 'banana', 'kiwi'], 'C': [10, 20, 60]}df2 = pd.DataFrame(data2)print("nDataFrame df2:")print(df2)
根据上述规则,期望的 df1 结果应为:
A B C new_col0 1 apple 10 Open1 2 banana 20 Open2 3 orange 30 New3 4 apple 40 New4 5 grape 50 New
3. 解决方案:使用 isin() 和 all(axis=1)
Pandas的 isin() 方法与NumPy的 where() 函数结合使用,能够高效地解决这个问题。
3.1 核心思路
元素级存在性检查 (isin(other_dataframe)): df1.isin(df2) 会生成一个与 df1 形状相同的布尔型DataFrame。对于 df1 中的每个元素 df1.at[i, col_name],它会检查该元素的值是否存在于 df2 的 对应列 df2[col_name] 中。如果存在,则结果DataFrame中对应位置为 True,否则为 False。行级所有元素匹配 (all(axis=1)): 在得到布尔型DataFrame后,我们使用 .all(axis=1) 方法。这会检查布尔型DataFrame的每一行,如果该行中的 所有 元素都是 True,则结果为 True,表示 df1 的该行所有值都在 df2 的对应列中找到了。条件赋值 (np.where()): 最后,NumPy的 np.where(condition, value_if_true, value_if_false) 函数根据上一步生成的布尔系列,为 df1 的新列 new_col 赋值。
3.2 代码实现
# 应用解决方案df1['new_col'] = np.where(df1.isin(df2).all(axis=1), 'Open', 'New')print("n更新后的 DataFrame df1:")print(df1)
3.3 结果解释
让我们逐步分析 df1.isin(df2).all(axis=1) 的执行过程:
标书对比王
标书对比王是一款标书查重工具,支持多份投标文件两两相互比对,重复内容高亮标记,可快速定位重复内容原文所在位置,并可导出比对报告。
58 查看详情
df1.isin(df2):
对于 df1 的第一行 (1, ‘apple’, 10):1 是否在 df2[‘A’] ([1, 2, 6]) 中?是 (True)。’apple’ 是否在 df2[‘B’] ([‘apple’, ‘banana’, ‘kiwi’]) 中?是 (True)。10 是否在 df2[‘C’] ([10, 20, 60]) 中?是 (True)。因此,第一行对应的布尔结果为 [True, True, True]。对于 df1 的第三行 (3, ‘orange’, 30):3 是否在 df2[‘A’] 中?否 (False)。’orange’ 是否在 df2[‘B’] 中?否 (False)。30 是否在 df2[‘C’] 中?否 (False)。因此,第三行对应的布尔结果为 [False, False, False]。df1.isin(df2) 会生成一个布尔型DataFrame,例如:
A B C0 True True True1 True True True2 False False False3 False True False4 False False False
.all(axis=1):
对于布尔型DataFrame的每一行,检查所有值是否都为 True。第一行 [True, True, True] -> True第二行 [True, True, True] -> True第三行 [False, False, False] -> False第四行 [False, True, False] -> False第五行 [False, False, False] -> False最终得到一个布尔型Series:[True, True, False, False, False]。
np.where(condition, ‘Open’, ‘New’):
根据上述布尔型Series,将 df1[‘new_col’] 赋值。True 对应 Open,False 对应 New。因此,new_col 的最终结果为 [‘Open’, ‘Open’, ‘New’, ‘New’, ‘New’],这与我们的预期完全一致。
4. 注意事项与扩展
列名匹配: isin(other_dataframe) 方法要求两个DataFrame的列名必须匹配。它会根据列名进行元素级比较。如果 df1 中存在 df2 中没有的列,或者反之,这些不匹配的列在 isin 结果中将全部为 False。性能: 对于大型DataFrame,isin() 方法通常比循环或合并操作更高效,因为它在底层使用了优化的C/Cython实现。严格行匹配与当前方法的区别:本教程的方法 (df1.isin(df2).all(axis=1)) 检查的是 df1 中某行的 每个元素 是否存在于 df2 的 对应列 中。如果需要进行 严格的行匹配(即 df1 的某一行是否作为一个 完整的行 存在于 df2 中),则需要采取其他策略,例如:将两个DataFrame转换为元组集合进行比较。使用 pd.merge(df1, df2, how=’left’, indicator=True),然后根据 _merge 列的值判断。将需要比较的列组合成一个唯一标识符(如字符串),然后使用 isin()。请务必根据实际业务需求选择合适的比较逻辑。在本例中,提供的解决方案恰好符合题意和期望输出。部分列比较: 如果只想比较 df1 和 df2 的部分列,可以在 isin() 之前先选择这些列,例如 df1[[‘A’, ‘B’]].isin(df2[[‘A’, ‘B’]]).all(axis=1)。
5. 总结
通过本教程,我们学习了如何利用Pandas的 isin() 方法结合NumPy的 np.where() 来实现DataFrame之间基于元素存在性的条件赋值。这种方法简洁高效,适用于需要根据复杂条件对DataFrame进行标记和分类的场景。理解 isin() 方法在接收DataFrame作为参数时的行为是关键,即它执行的是列与列之间的元素级匹配,再通过 all(axis=1) 聚合为行级判断。
以上就是Pandas DataFrame行级数据对比与条件赋值教程的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/619608.html
微信扫一扫
支付宝扫一扫