Pandas列匹配文件名生成路径列失败:为何全返回Null?
问题
我有6000个文件和一个包含URL列表的pandas DataFrame,部分URL与文件名匹配。遍历文件提取文本时,想为匹配URL的行添加对应的文件路径列,但代码始终返回Null,达不到预期效果。
现有代码
files = glob.glob("materials/*.html") data = pd.read_csv("file.csv") def match_name(row): if filename in row['URL']: return file for file in files: filename = os.path.basename(f'{file[:-5]}') extractor = open(file, 'rb') ... full = [p_text, os.path.basename(file)] df_full = pd.DataFrame(full) data['Path'] = dataset.apply(lambda x: match_name(x), axis=1)
也曾尝试:
data['Path'] = data.apply(lambda x: file if filename in x else None, axis=1)
DataFrame现有结构
| 名称 | 值 | URL |
|---|---|---|
| Name1 | Value1 | http://example.com/LALAC.html |
| Name2 | Value2 | http://example.com/ABASW.html |
| Name3 | Value3 | http://example.com/4421C.html |
文件列表示例
LALAC.txt、SDDSA1.txt、4421C.html等
期望输出
| 名称 | 值 | URL | 路径 |
|---|---|---|---|
| Name1 | Value1 | http://example.com/LALAC.html | materials/LALAC.txt |
| Name2 | Value2 | http://example.com/ABASW.html | None |
| Name3 | Value3 | http://example.com/4421C.html | materials/4421C.txt |
文件路径确实存在,但代码始终返回Null,问题出在哪?
问题分析与解决
核心问题点
- 循环覆盖问题:每次循环都重新赋值
data['Path'],最终只有最后一个文件的匹配结果会被保留,前面的匹配都会被覆盖,导致大部分行显示Null。 - 文件名处理错误:
file[:-5]是硬编码去掉5个字符,但.html后缀只有4个字符,会导致文件名截取错误;同时你有.txt后缀的文件,这种写法完全不适用。 - 变量名错误:代码里用了
dataset.apply,但你的DataFrame变量是data,这会直接报错,导致赋值失败。 - 匹配逻辑错误:尝试的代码里
filename in x,这里的x是行对象,不是URL列,应该明确指定x['URL']来检查匹配。 - 文件范围错误:原代码用
glob.glob("materials/*.html")只读取.html文件,但你需要匹配的文件包含.txt,所以应该扩大文件匹配范围。
修正后的代码
import glob import os import pandas as pd # 读取materials下所有类型的文件 files = glob.glob("materials/*") data = pd.read_csv("file.csv") # 构建「无后缀文件名-文件路径」的映射字典,提升匹配效率 file_map = {} for file in files: # 提取不带后缀的文件名 filename_no_ext = os.path.splitext(os.path.basename(file))[0] file_map[filename_no_ext] = file # 定义匹配函数,从映射字典中获取对应路径 def get_file_path(row): # 从URL中提取不带后缀的文件名 url_filename = os.path.splitext(os.path.basename(row['URL']))[0] return file_map.get(url_filename, None) # 一次性生成Path列 data['Path'] = data.apply(get_file_path, axis=1)
优化说明
- 用字典映射代替循环遍历DataFrame,6000个文件场景下效率大幅提升(字典查找为O(1))。
- 用
os.path.splitext统一处理文件名和URL中的文件名,避免硬编码字符数导致的截取错误。 - 一次性生成Path列,彻底解决循环覆盖的问题。
- 明确从URL的basename中提取无后缀名称,匹配逻辑更精准。
内容的提问来源于stack exchange,提问作者Octner
相关产品推荐
相关产品推荐

