0

0

Pandas 数据去重与ID序列化:高效向 DataFrame 添加新行

花韻仙語

花韻仙語

发布时间:2025-11-13 16:23:32

|

691人浏览过

|

来源于php中文网

原创

pandas 数据去重与id序列化:高效向 dataframe 添加新行

本教程详细介绍了如何使用 Pandas 高效地向现有 DataFrame 添加新数据,同时自动识别并移除重复项,并确保序列化的 ID 列能够正确更新。文章通过 `pd.concat` 和 `drop_duplicates` 的组合应用,展示了一种简洁且性能优越的数据处理方法,避免了传统迭代方式可能导致的索引和性能问题,确保数据完整性和一致性。

在数据处理和分析中,我们经常需要向现有数据集(通常以 Pandas DataFrame 的形式存在)添加新的记录。一个常见的挑战是,在添加新数据时,需要确保新记录不会与现有记录重复,并且如果数据中包含一个序列化的 ID 列,该列在添加新数据后仍能保持其连续性和正确性。本教程将介绍一种使用 Pandas 高效解决此问题的方法。

问题分析与传统方法局限

假设我们有一个包含 Id 和 Name 列的 DataFrame,其中 Id 是一个从0开始递增的唯一标识符。我们希望添加一个新项列表,但要排除那些 Name 值已经存在于 DataFrame 中的项,并在添加后重新生成连续的 Id。

传统上,一些用户可能会尝试通过迭代新项列表,并使用 df.append()(或其在 Pandas 2.0+ 中的替代方法 pd.concat([df, new_row_df]))逐行添加,然后再调用 df.drop_duplicates()。然而,这种方法存在几个问题:

  1. 性能问题: 逐行追加操作在处理大量数据时效率低下,因为它可能导致 DataFrame 的频繁重构。
  2. 索引管理: append() 或 pd.concat() 默认会保留原始索引,这可能导致在去重或重新排序后,索引变得不连续或重复。
  3. ID 列的复杂性: 如果在去重前尝试分配新的 Id,去重后可能导致 Id 不连续或存在跳跃。如果在去重后分配,则需要一种有效的方式来重新生成整个 Id 列。

高效解决方案:合并、去重与重置ID

Pandas 提供了一种更优雅、更高效的方法来处理这类场景,即结合使用 pd.concat() 进行数据合并,drop_duplicates() 进行去重,以及在去重后统一重置 Id 列。

1. 准备示例数据

首先,我们创建一个初始的 DataFrame 和要添加的新项列表。

import pandas as pd

# 初始 DataFrame
data = {'Id': [0, 1, 2, 3],
        'Name': ['Alpha', 'Beta', 'Gamma', 'Delta']}
df_original = pd.DataFrame(data)

print("原始 DataFrame:")
print(df_original)

# 待添加的新项列表
items_to_add = ["Epsilon", "Beta", "Zeta"]
print("\n待添加的新项:", items_to_add)

输出:

原始 DataFrame:
   Id   Name
0   0  Alpha
1   1   Beta
2   2  Gamma
3   3  Delta

待添加的新项: ['Epsilon', 'Beta', 'Zeta']

2. 将新项转换为 DataFrame

为了使用 pd.concat(),我们需要将 items_to_add 列表转换为一个 DataFrame。

Quillbot
Quillbot

一款AI写作润色工具,QuillBot的人工智能改写工具将提高你的写作能力。

下载
df_new_items = pd.DataFrame({"Name": items_to_add})
print("\n新项 DataFrame:")
print(df_new_items)

输出:

新项 DataFrame:
      Name
0  Epsilon
1     Beta
2     Zeta

3. 合并 DataFrame 并去重

现在,我们将原始 DataFrame 和新项 DataFrame 合并,然后基于 Name 列进行去重。drop_duplicates(subset="Name") 将会检查 Name 列,并默认保留每个重复项的第一个出现。

# 合并原始 DataFrame 和新项 DataFrame
# 注意:这里不需要对df_new_items使用ignore_index=True,因为后续会重新设置Id列
df_combined = pd.concat([df_original, df_new_items])

# 基于 'Name' 列去重,保留第一次出现的记录
df_final = df_combined.drop_duplicates(subset="Name", keep='first')

print("\n合并并去重后的 DataFrame (Id尚未重置):")
print(df_final)

输出:

合并并去重后的 DataFrame (Id尚未重置):
   Id     Name
0   0    Alpha
1   1     Beta
2   2    Gamma
3   3    Delta
0   NaN  Epsilon
2   NaN     Zeta

解释: 可以看到,Beta 因为在 df_original 中已经存在,所以被去重了。Epsilon 和 Zeta 是新添加的,它们在合并后的 df_combined 中被保留。但由于 df_new_items 中没有 Id 列,pd.concat 会自动填充 NaN。这正是我们下一步需要解决的问题。

4. 重置 Id 列

最后一步是为去重后的 DataFrame 重新生成一个连续的 Id 列。我们可以通过 range(len(df_final)) 来实现。

df_final["Id"] = range(len(df_final))

print("\n最终结果 DataFrame (Id已重置):")
print(df_final)

输出:

最终结果 DataFrame (Id已重置):
   Id     Name
0   0    Alpha
1   1     Beta
2   2    Gamma
3   3    Delta
4   4  Epsilon
5   5     Zeta

现在,Id 列已经正确地从0开始连续递增,并且所有重复的 Name 都已被移除。

完整代码示例

import pandas as pd

# 1. 初始 DataFrame
data = {'Id': [0, 1, 2, 3],
        'Name': ['Alpha', 'Beta', 'Gamma', 'Delta']}
df_original = pd.DataFrame(data)

print("原始 DataFrame:")
print(df_original)

# 2. 待添加的新项列表
items_to_add = ["Epsilon", "Beta", "Zeta"]
print("\n待添加的新项:", items_to_add)

# 3. 将新项转换为 DataFrame
df_new_items = pd.DataFrame({"Name": items_to_add})

# 4. 合并原始 DataFrame 和新项 DataFrame
df_combined = pd.concat([df_original, df_new_items])

# 5. 基于 'Name' 列去重,保留第一次出现的记录
df_final = df_combined.drop_duplicates(subset="Name", keep='first')

# 6. 重置 Id 列,确保其从0开始连续递增
df_final["Id"] = range(len(df_final))

print("\n最终处理结果:")
print(df_final)

# 如果需要保存到 CSV 文件
# df_final.to_csv('output.csv', index=False)

注意事项与最佳实践

  • keep 参数: drop_duplicates() 方法中的 keep 参数非常重要。
    • keep='first' (默认值):保留第一次出现的重复项。
    • keep='last':保留最后一次出现的重复项。
    • keep=False:删除所有重复项(即如果一个值出现多次,所有这些行都会被删除)。根据具体需求选择。在本教程中,我们希望保留原始数据中的项,因此 keep='first' 是合适的。
  • 性能: 使用 pd.concat() 结合 drop_duplicates() 是处理这类批量数据操作的高效方法,远优于循环逐行添加。
  • 索引: 在 pd.concat() 之后,DataFrame 的索引可能会变得混乱(例如,新添加行的索引可能从0开始重复)。但由于我们最终会重新设置 Id 列,并且 Id 列是我们的主要标识符,原始索引的混乱通常不是问题。如果需要一个干净的、从0开始的 Pandas 内部索引,可以在 df_final["Id"] = range(len(df_final)) 之后再调用 df_final = df_final.reset_index(drop=True)。
  • 数据类型: 确保 Name 列的数据类型一致,以便 drop_duplicates() 正确工作。

总结

通过结合使用 pd.concat() 进行高效的数据合并,drop_duplicates(subset="Name") 进行基于特定列的去重,以及 df["Id"] = range(len(df)) 进行 ID 列的重新序列化,我们可以优雅且高效地解决向 DataFrame 添加去重数据并维护连续 ID 的问题。这种方法不仅代码简洁,而且在处理大规模数据集时表现出卓越的性能。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

51

2025.12.04

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

299

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

179

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

277

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

252

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

121

2025.08.07

append用法
append用法

append是一个常用的命令行工具,用于将一个文件的内容追加到另一个文件的末尾。想了解更多append用法相关内容,可以阅读本专题下面的文章。

343

2023.10.25

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

97

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 45万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号