python 读取大文本文件并存入numpy时过于费时的问题及猜测

因需要读取大文本文件(约有1,300,000行,40兆),并简单处理存入numpy数组中,运行过程中发现随读取数据的增加,耗费时间显著增加,稍作修改后运行速度显著提升,不解,记之,希望大家帮忙解惑。

初步猜测(未验证):在原始代码中对numpy数组进行了vstack,而这个过程可能对已有数组进行了类似遍历的操作,才会出现随数组中数据增加产生时间上的显著增加。

1.原始代码

此代码在前期运行较快,在运行接近4,500行左右时,速度开始逐步变慢,最后花了很长时间也没能运行出结果,不知是何种原因。

def readTXT1(txt_file, separator='\t'):
    """
    读取单行文本数据(x y z i(or classification))
    :param txt_file: 待读取的文本
    :param separator: 待读取的文本中的分割符,如空格或制表符
    :return: 返回array数组,一行为一个数据
    """
    point = np.array([])
    with open(txt_file, 'r') as file:
        for line in file:
            point_tmp = line.split(separator)
            point_tmp = [x.strip() for x in point_tmp if x.strip() != '']
            point_tmp = list(map(float, point_tmp))
            point_one = np.array([point_tmp[0], point_tmp[1], point_tmp[2], point_tmp[3]])
            if np.shape(point)[0] > 0:
                point = np.vstack((point, point_one))
            else:
                point = np.array([point_one])
    print('% ', txt_file, 'has ', np.shape(point), 'points')
    return point

2.调整后代码

调整后先将数据存入list中,最后将list转换为array,此方案运行十分流畅,不足半分钟就已经完成读取与转化。相比原始代码只是少了一个判断和一个初始化array,但感觉问题应该不是出在此处,怀疑原始方案运行慢是因为叠置vstack。感觉只有在vstack过程中对已有数组进行了类似遍历的操作,才会出现随数组中数据增加产生时间上的显著增加。

def readTXT2(txt_file, separator='\t'):
    """
    读取单行文本数据(x y z i(or classification))
    :param txt_file: 待读取的文本
    :param separator: 待读取的文本中的分割符,如空格或制表符
    :return: 返回array数组,一行为一个数据
    """
    all_points = []
    with open(txt_file, 'r') as file:
        for line in file:
            point_tmp = line.split(separator)
            point_tmp = [x.strip() for x in point_tmp if x.strip() != '']
            point_tmp = list(map(float, point_tmp))
            all_points.append(point_tmp[0:4])
    print('list:', len(all_points))
    point = np.array(all_points)
    print('% ', txt_file, 'has ', np.shape(point), 'points')
    return point

 

<think>我们有一个文本文件,其中包含空格分隔的十六进制单字节数据(即每个数据是两位十六进制数,例如"FF"、"1A"等)。我们需要将其读取并存储为一个NumPy二维数组。每个字节数据将对应数组中的一个元素(整数类型)。步骤:1.读取文件:逐行读取文本文件。2.分割数据:每行按空格分割,得到一个字符串列表(每个字符串是一个两位十六进制数)。3.转换数据:将每个十六进制字符串转换为整数(注意:每个十六进制字符串表示一个字节,所以整数范围在0-255之间,因此我们可以使用uint8类型)。4.构建二维数组:将每行的整数列表组合成一个二维数组。注意:假设文件每行的数据个数相同(即每行有相同数量的十六进制数),这样我们可以构建一个矩形二维数组。示例文件内容(例如"data.txt"):0001020AFF107F8081我们要得到一个3x3的二维数组,数据类型为uint8,值分别为:[[0,1,2],[10,255,16],[127,128,129]]代码实现:</think>### 读取十六进制文本文件NumPy二维数组的方法 要读取包含空格分隔的十六进制单字节数据的文本文件并存储为NumPy二维数组,请按照以下步骤操作: #### 1. **读取文件并分割数据** ```python import numpy as np # 读取文件,按行分割并去除首尾空格 with open('hex_data.txt') as f: lines = [line.strip() for line in f.readlines()] # 将每行按空格分割成十六进制字符串列表 hex_rows = [line.split() for line in lines] ``` #### 2. **转换十六进制为整数** ```python # 将每个十六进制字符串转换为整数(0-255范围) int_data = [ [int(hex_str, 16) for hex_str in row] for row in hex_rows ] ``` #### 3. **创建NumPy二维数组** ```python # 转换为uint8类型的二维数组(单字节存储) arr = np.array(int_data, dtype=np.uint8) ``` #### 完整代码示例 ```python import numpy as np def read_hex_to_numpy(file_path): """读取十六进制文本文件NumPy二维数组""" with open(file_path) as f: lines = [line.strip() for line in f if line.strip()] hex_rows = [line.split() for line in lines] int_data = [[int(h, 16) for h in row] for row in hex_rows] return np.array(int_data, dtype=np.uint8) # 使用示例 hex_array = read_hex_to_numpy('data.txt') print(hex_array.shape) # 输出数组维度,如(3, 4) print(hex_array.dtype) # 输出uint8 print(hex_array) # 显示数组内容 ``` #### 关键说明: 1. **数据类型选择**: - 使用`np.uint8`(无符号8位整数)存储单字节数据,内存占用最小 - 每个元素表示范围$0$到$255$(即$00$到$FF$),完美匹配单字节十六进制值 2. **文件格式要求**: - 文件示例`data.txt`: ``` 00 1A FF 7F 80 3E C5 2F 0B ``` - 每行数据用空格分隔 - 支持空行自动跳过(`if line.strip()`过滤) 3. **验证输出**: ```python # 查看数组内容(十六进制格式) for row in hex_array: print([f"{x:02X}" for x in row]) # 输出: ['00', '1A', 'FF'], ['7F', '80', '3E'], ['C5', '2F', '0B'] ``` #### 性能优化建议 对于型文件($>1GB$): ```python # 使用生成器表达式减少内存占用 with open('large_data.txt') as f: arr = np.array([ [int(hex_str, 16) for hex_str in line.split()] for line in f if line.strip() ], dtype=np.uint8) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值