You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何快速读取含START/END标签的顶点数据文件?

问题描述

我有一个数据文件,部分内容如下:

START vertex 266.36 234.594 14.6145 vertex 268.582 234.968 15.6956 vertex 267.689 232.646 15.7283 END START vertex 166.36 23.594 4.6145 vertex 8.582 23.968 5.6956 vertex 67.689 32.646 1.7283 END # [...]

文件由多个包含三个vertex的块组成。我目前采用逐行读取的方式加载数据,但速度很慢,当前代码如下:

data = numpy.empty((n, 3))
flt = numpy.vectorize(float)
for k in range(n):
    parts = f.readline().decode('utf-8').split()
    assert len(parts) == 4
    assert parts[0] == 'vertex'
    data[k] = flt(parts[1:])

想请教下有什么可行的优化建议?

优化建议

嘿,看到你用逐行读取加numpy.vectorize的方式处理数据速度慢,太能理解了——Python的循环和频繁IO本来就是性能瓶颈,这里给你几个实用的优化方向,都是实际项目里验证过的:

  • 一次性读取整个文件,批量处理
    IO操作是最大的拖油瓶,逐行读取会频繁调用系统IO接口,不如一次性把整个文件内容读进来,再集中做字符串处理。比如:

    import numpy as np
    
    # 一次性读取全部内容,减少IO次数
    with open('your_file.txt', 'rb') as f:
        content = f.read().decode('utf-8')
    
    # 拆分所有字符串片段,筛选出vertex相关的数值
    tokens = content.split()
    # 找到所有标记为'vertex'的位置
    vertex_positions = [i for i, token in enumerate(tokens) if token == 'vertex']
    # 收集每个vertex后面的三个数值
    numeric_values = []
    for pos in vertex_positions:
        numeric_values.extend(tokens[pos+1 : pos+4])
    
    # 用numpy批量转换为浮点数组,比vectorize高效太多
    data = np.array(numeric_values, dtype=np.float64).reshape(-1, 3)
    

    这里把IO次数降到1次,而且用numpy的原生数组转换替代了vectorize——别被vectorize的名字骗了,它本质还是Python循环,根本不是真正的向量化操作,速度快不起来。

  • 用numpy内置的文本读取函数
    numpy自带的np.loadtxt或np.genfromtxt专门优化了文本读取,比手动循环高效得多。你可以先读取所有数据,再筛选出vertex开头的行:

    import numpy as np
    
    # 读取所有非注释行,按空格分隔
    all_rows = np.loadtxt('your_file.txt', dtype=str, comments='#')
    # 筛选第一列是'vertex'的行,再转换为浮点型
    vertex_data = all_rows[all_rows[:, 0] == 'vertex'][:, 1:].astype(np.float64)
    

    如果文件超大,内存放不下,还可以配合生成器用np.fromiter分批处理,但一般情况下,只要内存足够,这种方式比手动循环快好几倍。

  • 借助pandas处理大文件
    如果你的数据量特别大,pandas的文本读取工具内部做了很多底层优化,处理效率更高,代码也更简洁:

    import pandas as pd
    
    # 按空格分隔读取所有行,忽略注释
    df = pd.read_table('your_file.txt', sep='\s+', header=None, comment='#')
    # 筛选出第一列为'vertex'的行,提取后三列转为numpy数组
    data = df[df[0] == 'vertex'].iloc[:, 1:4].to_numpy(dtype=np.float64)
    

    pandas在处理大文本时的性能优势很明显,尤其是数据量超过百万行的时候。

  • 去掉不必要的断言
    原代码里的两个assert在调试阶段很有用,但如果是生产环境且你已经确认数据格式完全合规,去掉它们能节省不少额外的性能开销。

内容的提问来源于stack exchange,提问作者Nico Schlömer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:06:32