Numpy genfromtxt中names=True使用疑问:为何dtype显示为<U?
问题分析与解决
问题描述
我的test.csv文件表头为“A 1”和“A+2”,内容如下:
A 1,A+2 test& ,1 skip, #, N/A,NA
执行以下代码:
import numpy as np test = np.genfromtxt("test.csv", delimiter = ',', dtype = str, names = None )
得到正常输出:
array([['A 1', 'A+2'], ['test& ', '1'], ['skip', ''], ['N/A', 'NA']], dtype='<U10')
这里dtype='<U10'合理,因为'test& '包含10个字符。但将names=None改为names=True后,输出变为:
array([('', ''), ('', ''), ('', '')], dtype=[('A_1', '<U'), ('A2', '<U')])
表头被自动处理为“A_1”和“A2”,但dtype显示为<U,所有数据为空。
原因
当设置names=True时,genfromtxt会将第一行作为字段名并跳过该行,但在结构化数组模式下,仅指定dtype=str时,numpy不会自动扫描所有数据推断字符串长度,默认使用长度为0的Unicode字符串类型<U,导致所有数据解析失败。
解决办法
方法1:显式指定字符串长度的结构化dtype
直接定义每个字段的字符串长度,让genfromtxt明确知道如何解析:
import numpy as np test = np.genfromtxt("test.csv", delimiter = ',', dtype=[('A_1', 'U10'), ('A2', 'U10')], names = True )
执行后会得到正确的结构化数组,输出示例:
array([('test& ', '1'), ('skip', ''), ('#', ''), ('N/A', 'NA')], dtype=[('A_1', '<U10'), ('A2', '<U10')])
方法2:先读取数据再手动构造结构化数组
先以普通二维数组读取所有数据,再处理表头并构造结构化数组:
import numpy as np # 读取完整数据 data = np.genfromtxt("test.csv", delimiter = ',', dtype = 'U10', skip_header=0 ) # 提取并处理表头(模拟genfromtxt的默认字段名处理逻辑) headers = data[0] processed_headers = [h.replace(' ', '_').replace('+', '') for h in headers] # 构造结构化数组 test = np.array([tuple(row) for row in data[1:]], dtype=list(zip(processed_headers, ['U10']*len(processed_headers))))
这种方式更灵活,能自定义字段名的处理规则。
内容的提问来源于stack exchange,提问作者maxloo
相关产品推荐
相关产品推荐

