如何读取非CSV扩展名的类CSV文件并提取指定元数据?
处理自定义扩展名(WOC/WOL/WPL)的CSV数据并提取元信息
需求说明
手里有一批扩展名是WOC、WOL、WPL的数据集文件,本质是CSV结构,但前几行是格式杂乱的元信息(包含城市、身高、体重、年龄),从第3个非空行开始才是标准的DataFrame数据(表头为A、B、C、D、E)。需要优化读取逻辑,把元信息提取出来关联到每一行数据中。
示例文件开头结构:
Person:?,?;F dob. ? MT: ? Z:C NewYork Mon.:S St.? 144 cm/35 Kg/5 YearsOld 45,34,22,26,0 78,74,82,11,0
期望输出格式:
A, B, C, D, E, City, Height, Weight, Age 45,34,22,26,0,NewYork, 144, 35, 5 78,74,82,11,0,NewYork, 144, 35, 5
优化后的代码
import pandas as pd import glob import chardet import re from io import StringIO def process_custom_csv(file_path): # 检测文件编码,兼容多种编码格式 with open(file_path, 'rb') as f: encoding = chardet.detect(f.read())["encoding"] or 'utf-8' # 读取所有行并过滤空行,避免空行干扰元信息和数据的定位 with open(file_path, 'r', encoding=encoding) as f: lines = [line.strip() for line in f if line.strip()] # 至少需要3条非空行(2条元信息+1条数据),否则返回空DataFrame if len(lines) < 3: return pd.DataFrame() # 从第一条非空行提取城市:匹配Z:C后的单词 line1 = lines[0] city_match = re.search(r'Z:C (\w+)', line1) city = city_match.group(1) if city_match else None # 从第二条非空行提取身高、体重、年龄:提取行内所有数字 line2 = lines[1] nums = re.findall(r'\d+', line2) height, weight, age = nums[:3] if len(nums) >= 3 else (None, None, None) # 读取CSV数据部分:将剩余非空行转为可读取的CSV流 data_lines = lines[2:] df = pd.read_csv( StringIO('\n'.join(data_lines)), header=None, names=['A', 'B', 'C', 'D', 'E'] ) # 给每条数据添加元信息列 df['City'] = city df['Height'] = height df['Weight'] = weight df['Age'] = age return df # 批量处理所有目标扩展名文件 all_files = glob.glob('*.WOC') + glob.glob('*.WOL') + glob.glob('*.WPL') all_dfs = [process_custom_csv(f) for f in all_files if not process_custom_csv(f).empty] # 合并所有数据成最终DataFrame final_df = pd.concat(all_dfs, ignore_index=True) print(final_df)
核心优化细节
- 精准提取元信息:用正则表达式锁定城市(匹配
Z:C后的单词)和身高等数值(提取行内数字),不依赖固定行号,适配文件中空行波动的情况 - 高效读取数据:先过滤所有空行,直接从第3个非空行读取有效CSV数据,逻辑简单易懂,避免复杂的行号计算
- 批量处理提速:用列表推导式收集有效DataFrame,最后一次性合并,比循环
append效率高很多,尤其适合大量文件的场景 - 容错处理:元信息匹配失败或文件无有效数据时,会返回空DataFrame并跳过,避免程序崩溃
内容的提问来源于stack exchange,提问作者dspractician
相关产品推荐
相关产品推荐

