使用Pandas DataFrame Apply生成文件哈希时重复哈希问题排查
问题分析与解决
你遇到的问题根源在于函数内部的多个错误导致所有调用都复用了同一个全局文件路径,结合apply的参数传递逻辑,最终生成了相同的哈希值。我们逐个拆解问题:
1. 函数参数与路径获取错误
当使用df.apply(generate_hash, axis=1)时,传入generate_hash的是DataFrame的整行数据(Series对象),而不是单独的路径字符串。你的原函数里:
- 拼写错误:
paht['path']→ 应该是path['path'](这里的path是传入的行Series,需要通过列名'path'提取实际路径) - 如果不修正这个拼写,函数会抛出
NameError,但你提到执行后生成了哈希,说明可能后续改了拼写,但还有下一个致命错误。
2. 未定义变量file导致复用全局变量
原函数里with open(file, 'rb')中的file变量从未定义过!但你之前运行过for file in glob.glob(...)的循环,file会作为全局变量保留在命名空间中,值是循环的最后一个文件(也就是/path/file_5)。所以当apply调用函数时,每次都打开这个全局的file路径,自然所有行生成的都是file_5的哈希值。
3. apply的语法错误(原代码注释提到的括号问题)
原代码里如果把df.apply(generate_hash, axis=1)错写成df.apply(generate_hash(axis=1)),会直接执行函数而非传递引用,但你提到执行后生成了哈希,说明这个错误可能已经修正,但前面的两个错误才是核心。
修正后的代码
我们把函数逻辑梳理正确,确保每次调用都使用当前行的路径:
import hashlib import pandas as pd def generate_hash(row): # 从传入的行Series中提取路径 path = row['path'] BLOCK_SIZE = 10485760 # 10MB块大小 file_hash = hashlib.sha256() # 增加异常处理,避免文件不存在/权限问题导致崩溃 try: with open(path, 'rb') as f: fb = f.read(BLOCK_SIZE) while len(fb) > 0: file_hash.update(fb) fb = f.read(BLOCK_SIZE) return file_hash.hexdigest() except FileNotFoundError: return None # 或返回自定义错误标识 except PermissionError: return "permission_denied" # 应用到DataFrame df['hash'] = df.apply(generate_hash, axis=1)
额外优化建议
- 如果你的DataFrame行数很多,
apply是逐行处理,效率较低。可以考虑用swifter库自动选择最优方式加速,或者改用multiprocessing并行处理文件哈希。 - 可以先对
path列做有效性校验,过滤掉不存在的文件路径后再生成哈希。
内容的提问来源于stack exchange,提问作者Thagor
相关产品推荐
相关产品推荐

