跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python算法

五种精确身份证号匹配算法设计与实现

对从大表中匹配小表身份证号的需求,设计了五种算法:暴力循环、Pandas isin、Pandas Merge、SQLite 数据库及分块处理。通过代码实现与性能对比,指出暴力法效率极低不推荐;Pandas isin 和 Merge 速度最快(<1 秒),为首选方案;SQLite 适合复杂逻辑或海量数据;分块处理用于解决内存不足问题。最终建议根据数据规模选择合适方法。

芝士奶盖发布于 2026/3/27更新于 2026/10/282 浏览
五种精确身份证号匹配算法设计与实现

设计五种算法精确的身份证号匹配

问题定义与数据准备

我们有两个 Excel 文件:

  • small.xlsx: 包含约 5,000 条记录。
  • large.xlsx: 包含约 140,000 条记录。

目标:快速、高效地从 large.xlsx 中找出所有其'身份证号'字段存在于 small.xlsx'身份证号'字段中的记录,并将这些匹配的记录保存到一个新的 Excel 文件 result.xlsx 中。

假设:身份证号字段名在两个表中都是 id_card。

首先,进行准备工作,安装必要的库并模拟一些数据用于测试和性能估算。

pip install pandas openpyxl
import pandas as pd
import time
import random

# 为演示和测试,我们可以创建一些模拟数据(实际中使用 pd.read_excel 读取你的文件)
def generate_id_card():
    """生成一个模拟的 18 位身份证号"""
    region_code = random.choice(['110101', '310104', '440301'])  # 随机地区码
    birth_date = f"19{random.randint(50, 99):02d}{random.randint(1, 12):02d}{random.randint(1, 28):02d}"
    sequence_code = f"{random.randint(0, 999):03d}"  # 顺序码
    check_code = random.choice(['X', '0', '1', '2', '3', '4', '5', '6', '7', '8', ])  
     region_code + birth_date + sequence_code + check_code


small_data = {: [generate_id_card()  _  ()]}
small_df = pd.DataFrame(small_data)
small_df.to_excel(, index=)


large_list = []
ids_from_small = small_df[].tolist()
overlap_ids = random.sample(ids_from_small, )
 _  ():
     random.random() <   overlap_ids:
        id_to_use = random.choice(overlap_ids)
    :
        id_to_use = generate_id_card()
    large_list.append(id_to_use)

large_data = {: large_list, : [] * }
large_df = pd.DataFrame(large_data)
large_df.to_excel(, index=)
()
()
()
'9'
# 校验码
return
# 生成小表数据 (5000 条)
'id_card'
for
in
range
5000
'small.xlsx'
False
# 生成大表数据 (140000 条),并确保其中包含一部分小表中的 ID
'id_card'
3000
for
in
range
140000
if
0.02
and
else
'id_card'
'other_data'
'Some other info'
140000
'large.xlsx'
False
print
"模拟数据生成完成!"
print
f"小表尺寸:{small_df.shape}"
print
f"大表尺寸:{large_df.shape}"

现在,我们开始设计算法。


算法一:暴力双重循环 (Brute Force Double Loop)

原理与步骤

这是最直观、最基础的方法。

  1. 加载数据:将两个 Excel 表分别读入 Pandas DataFrame,small_df 和 large_df。
  2. 嵌套循环:
    • 外层循环遍历 large_df 的每一行(140,000 次迭代)。
    • 内层循环遍历 small_df 的每一行(5,000 次迭代)。
    • 对于每一对 (large_id, small_id),比较它们是否相等。
  3. 收集结果:如果相等,则将 large_df 的当前行标记为匹配。
  4. 保存结果:将所有标记的行提取出来,保存到新的 Excel 文件。

Python 实现

def algorithm_1_brute_force(small_file, large_file, output_file):
    """ 算法 1:暴力双重循环 """
    print("算法 1:暴力双重循环 - 开始执行")
    start_time = time.time()
    
    # 1. 加载数据
    small_df = pd.read_excel(small_file)
    large_df = pd.read_excel(large_file)
    
    # 确保 id_card 列是字符串类型,避免因数据类型导致的匹配失败
    small_df['id_card'] = small_df['id_card'].astype(str)
    large_df['id_card'] = large_df['id_card'].astype(str)
    
    # 获取小表的身份证号列表
    small_ids = small_df['id_card'].tolist()
    
    # 2. 嵌套循环比对
    matched_rows = []  # 存储匹配的行索引或行数据
    large_ids = large_df['id_card'].tolist()
    
    for i, large_id in enumerate(large_ids):
        for small_id in small_ids:
            if large_id == small_id:
                matched_rows.append(i)  # 记录匹配的行索引
                break  # 找到一个匹配就可以跳出内层循环,进入下一个大表 ID
    
    # 3. 收集结果
    result_df = large_df.iloc[matched_rows]
    
    # 4. 保存结果
    result_df.to_excel(output_file, index=False)
    
    end_time = time.time()
    execution_time = end_time - start_time
    print(f"算法 1 完成。找到 {len(result_df)} 条匹配记录。耗时:{execution_time:.4f} 秒")
    return execution_time

优劣对比

  • 优点:
    • 实现极其简单,逻辑清晰,无需任何复杂的数据结构知识。
    • 无需额外内存(除了存储结果)。
  • 缺点:
    • 时间复杂度极高:O(n * m),其中 n 是 large 表大小(140,000),m 是 small 表大小(5,000)。总计 700,000,000 次比较。
    • 预计运行时间:在实际的 Pandas 操作中,由于循环开销,速度会更慢,预计需要 30 分钟到数小时。绝对不推荐用于生产环境。

算法二:利用 Pandas 的 isin() 方法

原理与步骤

这是对暴力算法的极大优化,利用了 Pandas 内置的高效向量化操作。

  1. 加载数据:同算法一。
  2. 创建查询集合:将 small_df 的'身份证号'列转换为一个 Python 集合(Set)。集合是基于哈希表实现的,其 in 操作的查询时间复杂度是平均 O(1)。
  3. 向量化筛选:使用 Pandas 的 isin() 方法。该方法会接收一个集合或列表,并返回一个布尔序列(Series),指示 large_df 的'身份证号'列中的每个元素是否存在于给定的集合中。
  4. 布尔索引:使用这个布尔序列对 large_df 进行索引,快速筛选出所有匹配的行。
  5. 保存结果:同算法一。

Python 实现

def algorithm_2_pandas_isin(small_file, large_file, output_file):
    """ 算法 2:利用 Pandas 的 isin 和集合 """
    print("算法 2:Pandas isin() - 开始执行")
    start_time = time.time()
    
    # 1. 加载数据
    small_df = pd.read_excel(small_file)
    large_df = pd.read_excel(large_file)
    small_df['id_card'] = small_df['id_card'].astype(str)
    large_df['id_card'] = large_df['id_card'].astype(str)
    
    # 2. 创建查询集合
    target_set = set(small_df['id_card'])
    
    # 3. 向量化筛选
    mask = large_df['id_card'].isin(target_set)
    
    # 4. 使用布尔索引获取结果
    result_df = large_df[mask]
    
    # 5. 保存结果
    result_df.to_excel(output_file, index=False)
    
    end_time = time.time()
    execution_time = end_time - start_time
    print(f"算法 2 完成。找到 {len(result_df)} 条匹配记录。耗时:{execution_time:.4f} 秒")
    return execution_time

优劣对比

  • 优点:
    • 实现非常简单,代码非常简洁。
    • 速度极快。isin() 是 Pandas 内部用 C 优化过的向量化操作,背后通常也使用了哈希表机制。它的时间复杂度可以近似看作是 O(n)。
    • 内存使用可控。
  • 缺点:
    • 本质上还是需要将小表的数据完全加载到内存中构建集合。
    • 对于极端海量数据(例如小表有上亿条),构建集合可能成为瓶颈,但在本场景(5000 条)中完全不是问题。
  • 预计运行时间:1 秒以内。这是处理此类问题的首选标准方法。

算法三:Pandas Merge(合并)

原理与步骤

利用数据库的 INNER JOIN 思想,使用 Pandas 的合并功能。

  1. 加载数据:同算法一。
  2. 执行内连接:使用 pd.merge() 函数,以'身份证号'作为连接键,对两个 DataFrame 进行内连接。内连接的特性是只会保留两个表中键值匹配的行。
  3. 保存结果:连接的结果就是我们需要的数据,直接保存即可。

Python 实现

def algorithm_3_pandas_merge(small_file, large_file, output_file):
    """ 算法 3:Pandas Merge (Inner Join) """
    print("算法 3:Pandas Merge - 开始执行")
    start_time = time.time()
    
    # 1. 加载数据
    small_df = pd.read_excel(small_file)
    large_df = pd.read_excel(large_file)
    small_df['id_card'] = small_df['id_card'].astype(str)
    large_df['id_card'] = large_df['id_card'].astype(str)
    
    # 2. 执行内连接
    # on 参数指定连接的列名。how='inner'表示内连接。
    result_df = pd.merge(large_df, small_df[['id_card']], on='id_card', how='inner')
    
    # 3. 保存结果
    result_df.to_excel(output_file, index=False)
    
    end_time = time.time()
    execution_time = end_time - start_time
    print(f"算法 3 完成。找到 {len(result_df)} 条匹配记录。耗时:{execution_time:.4f} 秒")
    return execution_time

优劣对比

  • 优点:
    • 实现极其简洁,语义清晰,一看就懂是做连接操作。
    • 速度非常快。Pandas 的 merge 函数底层也经过了高度优化,通常基于哈希或排序 - 合并算法,效率很高。
    • 可以轻松处理更复杂的连接条件(多列作为键)。
  • 缺点:
    • 会比 isin() 方法产生一些额外的中间开销,因为需要协调两个表的列。
    • 如果连接键不唯一,可能会产生笛卡尔积,导致结果行数爆炸(但身份证号是唯一的,所以不存在这个问题)。
  • 预计运行时间:1 秒左右。与算法二同为首选标准方法。

算法四:使用数据库(SQLite)

原理与步骤

将数据加载到内存数据库(如 SQLite)中,使用 SQL 语言的 IN 或 JOIN 语句来让数据库引擎完成高效的查找工作。

  1. 创建内存数据库:使用 sqlite3 模块在内存中创建一个临时数据库。
  2. 导入数据:将两个 Pandas DataFrame 分别写入数据库中的两个表。
  3. 执行 SQL 查询:编写 SQL 查询语句。
  4. 获取结果:将 SQL 查询的结果读回一个 Pandas DataFrame。
  5. 保存结果:同算法一。

Python 实现

import sqlite3

def algorithm_4_sqlite(small_file, large_file, output_file):
    """ 算法 4:使用 SQLite 内存数据库 """
    print("算法 4:SQLite 内存数据库 - 开始执行")
    start_time = time.time()
    
    # 1. 加载数据
    small_df = pd.read_excel(small_file)
    large_df = pd.read_excel(large_file)
    small_df['id_card'] = small_df['id_card'].astype(str)
    large_df['id_card'] = large_df['id_card'].astype(str)
    
    # 2. 创建内存数据库连接
    conn = sqlite3.connect(':memory:')
    
    # 3. 导入数据到数据库
    small_df.to_sql('small_table', conn, index=False)
    large_df.to_sql('large_table', conn, index=False)
    
    # 4. 编写并执行 SQL 查询
    query = """ SELECT large_table.* FROM large_table WHERE large_table.id_card IN (SELECT id_card FROM small_table) """
    result_df = pd.read_sql_query(query, conn)
    
    # 5. 关闭连接
    conn.close()
    
    # 6. 保存结果
    result_df.to_excel(output_file, index=False)
    
    end_time = time.time()
    execution_time = end_time - start_time
    print(f"算法 4 完成。找到 {len(result_df)} 条匹配记录。耗时:{execution_time:.4f} 秒")
    return execution_time

优劣对比

  • 优点:
    • 非常高效。SQLite 等数据库引擎是专门为快速数据查询而设计的。
    • 处理海量数据时优势更明显。如果数据量大到 Pandas 操作困难,可以改用磁盘数据库,并显式创建索引。
    • 可以利用强大的 SQL 语法处理极其复杂的匹配逻辑。
  • 缺点:
    • 实现步骤稍多,需要将数据导入导出数据库,增加了额外的 I/O 开销。
    • 对于这种规模的问题,其性能通常略慢于纯 Pandas 的向量化操作。
  • 预计运行时间:1-3 秒。在数据量极大(数千万以上)或匹配逻辑复杂时,此方法优势会显现。

算法五:分块处理 (Chunking)

原理与步骤

这个算法并非用于提升速度,而是用于解决内存不足的问题。当 large.xlsx 文件巨大(例如几个 GB),无法一次性读入内存时,就需要使用此方法。

  1. 加载小数据:将 small.xlsx 全部读入内存,并创建集合 S。
  2. 分块读取大数据:使用 Pandas 的 read_excel() 的 chunksize 参数,分批读取 large.xlsx。
  3. 逐块处理:对于每个数据块,使用 isin(S) 方法筛选出匹配的行。
  4. 累积结果:将每个块的处理结果追加到一个列表中,或者直接写入结果文件。
  5. 合并保存结果:处理完所有块后,将累积的结果合并并保存。

Python 实现

def algorithm_5_chunking(small_file, large_file, output_file, chunksize=10000):
    """ 算法 5:分块处理(用于内存不足的大文件场景) """
    print("算法 5:分块处理 - 开始执行")
    start_time = time.time()
    
    # 1. 加载小数据并创建集合
    small_df = pd.read_excel(small_file)
    small_df['id_card'] = small_df['id_card'].astype(str)
    target_set = set(small_df['id_card'])
    
    # 2. 初始化一个列表来存储每个块的结果
    chunks_result_list = []
    
    # 3. 分块读取大数据
    chunk_reader = pd.read_excel(large_file, chunksize=chunksize)
    for chunk in chunk_reader:
        chunk['id_card'] = chunk['id_card'].astype(str)
        
        # 4. 处理当前块
        mask = chunk['id_card'].isin(target_set)
        filtered_chunk = chunk[mask]
        chunks_result_list.append(filtered_chunk)
        print(f"已处理一个数据块,该块找到 {len(filtered_chunk)} 条匹配记录。")
    
    # 5. 合并结果并保存
    if chunks_result_list:
        final_result_df = pd.concat(chunks_result_list, ignore_index=True)
    else:
        final_result_df = pd.DataFrame()
    
    final_result_df.to_excel(output_file, index=False)
    
    end_time = time.time()
    execution_time = end_time - start_time
    print(f"算法 5 完成。找到 {len(final_result_df)} 条匹配记录。耗时:{execution_time:.4f} 秒")
    return execution_time

优劣对比

  • 优点:
    • 内存友好。核心优势是能够处理大于内存的数据文件。
    • 结合了 Pandas 向量化操作的效率。
  • 缺点:
    • 速度可能稍慢:由于需要多次读取文件、循环处理每个块,会产生额外的 I/O 开销。
    • 实现稍复杂。
  • 预计运行时间:2-5 秒。只有在处理超大文件、内存不足时才需要使用。

总结与最终对比

我们将五种算法的优缺点和适用场景总结如下:

算法优点缺点预计时间推荐度
1. 暴力循环实现简单速度极慢,无法忍受~30 分钟以上⭐(绝不推荐)
2. Pandas isin()实现简单,速度最快需要内存容纳小表集合<1 秒⭐⭐⭐⭐⭐(首选)
3. Pandas Merge实现简单,速度最快略有额外开销~1 秒⭐⭐⭐⭐⭐(首选)
4. SQLite高效,支持复杂查询,海量数据优势步骤稍多,数据迁移开销1-3 秒⭐⭐⭐⭐(备用方案)
5. 分块处理内存友好,可处理超大文件速度较慢,实现稍复杂2-5 秒⭐⭐⭐(特殊场景)

最终结论与建议:

  1. 对于你的具体问题(5000 条 vs 140000 条):
    • 毫不犹豫地选择算法二(isin())或算法三(merge())。它们是专门为这种表格数据操作设计的,代码简洁、效率最高。
  2. 如果你的小表也变得非常大(例如上百万条):
    • 算法二和三仍然有效,但创建集合或进行合并的内存消耗会变大。此时需要确保你的机器有足够 RAM。
  3. 如果你的大表巨大(例如几十 GB,无法读入内存):
    • 选择算法五(分块处理),它是解决此类问题的标准范式。
  4. 如果你的匹配逻辑变得非常复杂(不仅仅是相等匹配):
    • 考虑使用算法四(SQLite),利用 SQL 强大的表达能力来编写复杂查询。
  5. 算法一(暴力循环):永远只存在于教学示例中,用于提醒大家时间复杂度的重要性。

代码执行:你可以创建一个主函数来运行和比较这些算法(除了算法一)。

if __name__ == '__main__':
    files = ('small.xlsx', 'large.xlsx')
    times = {}
    times['alg_2'] = algorithm_2_pandas_isin(*files, 'result_2.xlsx')
    times['alg_3'] = algorithm_3_pandas_merge(*files, 'result_3.xlsx')
    times['alg_4'] = algorithm_4_sqlite(*files, 'result_4.xlsx')
    times['alg_5'] = algorithm_5_chunking(*files, 'result_5.xlsx', chunksize=50000)
    
    print("\n=== 所有算法耗时对比 ===")
    for alg, t in times.items():
        print(f"{alg}: {t:.4f} 秒")

在实际运行中,你会看到算法二和三以绝对优势胜出。

目录

  1. 设计五种算法精确的身份证号匹配
  2. 问题定义与数据准备
  3. 为演示和测试,我们可以创建一些模拟数据(实际中使用 pd.read_excel 读取你的文件)
  4. 生成小表数据 (5000 条)
  5. 生成大表数据 (140000 条),并确保其中包含一部分小表中的 ID
  6. 算法一:暴力双重循环 (Brute Force Double Loop)
  7. 原理与步骤
  8. Python 实现
  9. 优劣对比
  10. 算法二:利用 Pandas 的 isin() 方法
  11. 原理与步骤
  12. Python 实现
  13. 优劣对比
  14. 算法三:Pandas Merge(合并)
  15. 原理与步骤
  16. Python 实现
  17. 优劣对比
  18. 算法四:使用数据库(SQLite)
  19. 原理与步骤
  20. Python 实现
  21. 优劣对比
  22. 算法五:分块处理 (Chunking)
  23. 原理与步骤
  24. Python 实现
  25. 优劣对比
  26. 总结与最终对比

更多推荐文章

查看全部
  • 大模型学习误区:为何理论与实践需要相结合
  • Python 下载 ERA5-Land 气象数据的三种方法
  • AI 辅助 FPGA 开发:Vivado 配置与智能编程实践
  • 使用 Web Unlocker API 获取亚马逊数据教程
  • Vheer:免费免登录 AI 绘画视频生成与智能编辑工具
  • Spring AI 快速入门与实战指南
  • Python pytesseract 库:图像文字识别原理与实战
  • ROS2 功能包创建与 CMake 编译链路详解
  • Flutter for OpenHarmony 集成 dart_openai 接入 AI 大模型
  • 使用 llama.cpp 在普通电脑运行大模型实战
  • RV1106 基于 libdatachannel 的 4G WebRTC 实时视频传输方案
  • 2024 年 OpenCV 学习指南:从入门到实战
  • 无人机安全测试工具 Drone Hacking Tool 使用指南
  • GitHub Copilot 接入第三方 OpenAI 兼容模型及去除安全限制方法
  • ROS2 Humble 下基于 slam_toolbox 与 RPLidar 建图实战
  • Pyenv shell 命令临时切换 Python 版本
  • Stable-Diffusion-v1-5 开源协作:GitHub Issue 驱动的问题解决闭环
  • 高鋒集團與 Web3Labs:以資本與生態賦能傳統企業 Web3 轉型
  • 基于 ESP32-S3 芯片的 Wi-Fi 智能机器人系统设计
  • OpenAI 与 Anthropic 首席产品官分享 AI 产品设计经验

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online