如何将无分隔符的.geno数字矩阵导入Python并解决读取异常
问题根源
- 直接用
pd.read_csv('22_chr.geno')读取时,pandas默认以逗号为分隔符,你的文件没有逗号分隔符,会把整行内容全部识别为单列文本,最终只生成1列。 - 用numpy读取时,若直接将无分隔的长数字串按数值类型解析,序列长度对应的数值远超过整数类型的存储上限,会触发溢出,最终被识别为inf,完全无法得到正确结构。
- 你的文件本质是每行结构为:行索引标签 + 连续拼接的单字符基因型值(0/1/2/9),共2054个基因型列,列之间没有专门的分隔符,因此核心处理逻辑是先拆分每行的标签部分与基因型序列部分,再逐字符将每个基因型值拆分为独立列。
可落地的读取方案
pandas 实现(无需额外依赖)
import pandas as pd # 第一步:读取行标签与原始基因型字符串,不做列内拆分 raw_data = pd.read_csv( '22_chr.geno', sep=r'\s+', # 自动匹配标签与基因型串之间的任意长度空白分隔 header=None, names=['row_label', 'geno_string'] ) # 第二步:将连续的基因型字符串逐字符拆分为独立列 geno_matrix = pd.DataFrame( raw_data['geno_string'].apply(list).tolist() ).astype(int) # 将行标签设置为矩阵索引 geno_matrix.index = raw_data['row_label'].values
如果文件中标签与基因型串之间是固定制表符分隔,可以把sep=r'\s+'换成sep='\t',读取效率会更高。
numpy 快速实现(适合大体积文件)
如果文件行数较多,pandas的逐行处理速度偏慢,可以用纯numpy逻辑读取,处理效率更高:
import numpy as np # 读取全文件的行文本 with open('22_chr.geno', 'r') as f: lines = f.read().splitlines() row_labels = [] geno_sequences = [] for line in lines: # 按空白拆分,第一部分为行标签,剩余部分拼接为完整基因型串 line_parts = line.split() row_labels.append(int(line_parts[0])) full_geno_str = ''.join(line_parts[1:]) geno_sequences.append(list(full_geno_str)) # 转换为整数基因型矩阵 full_geno = np.array(geno_sequences, dtype=int) full_geno_labels = np.array(row_labels)
常见注意事项
不要直接给pandas的
read_csv传sep=''尝试按单字符拆分,该参数在新版pandas中会触发兼容性警告,且对长行的处理效率极低,稳定性差。
之前出现的numpy读取全为inf的问题,本质是把整串数十位的长数字当作单个整数解析,超出了int64的存储范围。只要先将字符串拆分为单个字符,再逐字符转成1位整数,就不会出现溢出问题。
拆分完成后可以通过full_geno.shape检查列数是否为2054,若存在不一致,仅需调整行内的拆分规则,排查是否有多余空格打断基因型序列即可。
内容的提问来源于stack exchange,提问作者Dr. Emil Nyerki
相关产品推荐
相关产品推荐

