如何将GB级TXT文件导入Python Numpy数组并实现多正则替换?
处理大GB级TXT文件并导入Numpy数组的优化方案
嘿,别担心,新手碰到大文件处理的性能问题太正常了!我来帮你优化代码,既能完成正则替换,又能保持低内存占用,还不用多次遍历文件~
首先梳理下你的核心需求:
- 替换表头的
Date, Time为DateTime - 替换每行中日期和时间之间的
,(第一个逗号空格)为可解析的分隔符(我猜你是想把日期时间合并成标准格式,比如用T分隔?不然连在一起的字符串没法转成datetime64) - 低内存处理GB级文件,避免一次性加载全部内容
- 高效导入Numpy数组
问题分析
你的现有代码有两个主要性能隐患:
- 列表推导式
[regex1.sub(...) for line in f_input]会把整个文件的行都加载到内存里,GB级文件很容易爆内存 - 注释掉的第二行又会重新遍历一次文件,双重遍历对大文件来说非常耗时
优化后的代码
import numpy as np import re # 编译正则表达式,提升重复匹配性能 regex_header = re.compile('Date, Time') regex_datetime_sep = re.compile(',\s', re.UNICODE) def process_line(line): # 先处理表头替换,再处理行内容的日期时间分隔符 modified_line = regex_header.sub('DateTime', line) # 只替换每行的第一个逗号空格(日期和时间之间的分隔),换成'T'方便解析 modified_line = regex_datetime_sep.sub('T', modified_line, count=1) return modified_line def convert_datetime(dt_str): # 直接用numpy解析datetime字符串,比先转datetime对象更快 return np.datetime64(dt_str.decode('utf-8'), 's') # 用生成器逐行处理,不加载全文件到内存 with open("Data.txt", 'r', encoding='utf-8') as f_input: processed_lines = (process_line(line) for line in f_input) array = np.genfromtxt( processed_lines, delimiter=", ", names=True, converters={"DateTime": convert_datetime}, dtype=[('DateTime', 'datetime64[s]'), ('Open', 'i4'), ('High', 'i4')], autostrip=True )
关键优化点说明
- 生成器代替列表推导式:
(process_line(line) for line in f_input)是生成器表达式,只会在需要的时候逐行读取、处理,不会把整个文件存到内存里,完美适配GB级文件 - 一次性完成多行正则替换:在
process_line函数里,对每行先处理表头替换,再处理日期时间分隔符替换,只遍历文件一次,大幅提升效率 - 优化datetime转换:直接用
np.datetime64解析字符串,省去了datetime.strptime的中间步骤,速度更快,而且更贴合Numpy的类型系统 - 保持正则编译:你之前编译正则的做法非常正确,编译后的正则重复匹配时性能会提升很多,继续保持
额外提示
如果你的文件里, 分隔符是固定的,也可以考虑不用正则替换日期时间的分隔,直接用字符串操作,比如:
def process_line(line): if line.startswith('Date, Time'): return 'DateTime, Open, High\n' # 分割第一个逗号空格,合并成带T的日期时间 dt_part, rest = line.split(', ', 1) return f"{dt_part.replace(', ', 'T')}, {rest}"
这种方法对于固定格式的字符串,可能比正则更快,你可以根据实际情况测试选择~
内容的提问来源于stack exchange,提问作者user7000656
相关产品推荐
相关产品推荐

