读取txt文件时如何系统性跳过含异常字符及额外列的行?
处理带异常行的文本文件读取问题
这种带随机乱码、额外列的脏数据确实很头疼,np.loadtxt因为对格式要求严格,确实没有直接跳过异常行的参数,但我们可以用几种更灵活的方法来解决:
方法一:用np.genfromtxt容错处理
np.genfromtxt比loadtxt更灵活,支持将无效行标记为NaN,之后我们可以过滤掉这些含NaN的行。修改你的代码如下:
import numpy as np from io import StringIO def Read(filename): # 处理分隔符 s = open(filename).read().replace(':',' ').replace(',',' ').replace('/',' ') # 使用genfromtxt,invalid_raise=False避免报错,自动将无效行设为NaN data = np.genfromtxt(StringIO(s), usecols=(4,5,6,8,9,10,11,12), invalid_raise=False) # 过滤掉含NaN的行(也就是异常行) data = data[~np.isnan(data).any(axis=1)] return data
这个方法的好处是改动小,利用numpy自带的函数就能搞定,但如果异常行的列数偏差太大,可能还是会有部分问题。
方法二:手动逐行过滤(最灵活)
如果异常情况比较复杂(比如乱码导致数值无法识别、列数完全不对),手动遍历每一行并验证是最稳妥的方式。我们可以先处理每一行的分隔符,然后检查列数是否符合要求,或者尝试转换数值,只有合法的行才保留:
import numpy as np from io import StringIO def Read(filename): valid_rows = [] with open(filename, 'r') as f: for line in f: # 处理当前行的分隔符 processed_line = line.replace(':',' ').replace(',',' ').replace('/',' ') # 分割成元素,过滤空字符串 elements = [elem for elem in processed_line.split() if elem.strip()] # 检查列数是否符合我们需要提取的列的要求(原usecols是4-12,共8列,所以原行至少要有13个元素) if len(elements) >= 13: try: # 尝试转换需要的列到数值 selected = [float(elements[i]) for i in (4,5,6,8,9,10,11,12)] valid_rows.append(selected) except ValueError: # 转换失败说明是异常行,跳过 continue # 转换为numpy数组 return np.array(valid_rows)
这种方法可以精准控制哪些行保留,不管是乱码还是额外列的情况都能处理,适合数据脏得比较厉害的场景。
方法三:用Pandas快速处理
如果你的项目允许使用Pandas,那处理这种脏数据会更简单,pandas.read_csv有专门的参数跳过异常行:
import pandas as pd import numpy as np def Read(filename): # 读取文件,设置分隔符为任意空白字符,跳过异常行 df = pd.read_csv(filename, sep='\s+', on_bad_lines='skip', header=None) # 提取需要的列(对应原usecols的4,5,6,8,9,10,11,12,注意Pandas列索引从0开始) selected_cols = df.iloc[:, [4,5,6,8,9,10,11,12]] # 转换为numpy数组 return selected_cols.to_numpy()
这里on_bad_lines='skip'会自动跳过那些格式错误的行,非常省心,而且Pandas处理这类文本文件的效率也很高。
内容的提问来源于stack exchange,提问作者Martín Manuel Gómez Míguez
相关产品推荐
相关产品推荐

