使用np.genfromtxt读取CSV时转换器出现额外1值行问题
问题:np.genfromtxt转换器中出现额外的
b'1'输出原因 我在使用np.genfromtxt读取CSV文件时,尝试通过converters参数对各列做预处理,但运行后发现转换器的打印输出开头多了一行b'1'的调用记录,这个值并没有出现在最终的输出数组里,请问这是怎么回事?
CSV文件内容
"","Col1","Col2","Col3" "1","Cell.1",NA,1 "2","Cell.2",NA,NA "3","Cell.3",1,NA "4","Cell.4",NA,NA "5","Cell.5",NA,NA "6","Cell.6",1,NA
我的代码
import numpy as np filename = 'b.csv' h = ("", "Col1", "Col2", "Col3") def col1_converter(v): print(f'col1_converter {v = }') return v def col2_converter(v): print(f'col2_converter {v = }') return v def col3_converter(v): print(f'col3_converter {v = }') return v a = np.genfromtxt( filename, delimiter=',', names=True, dtype=[None, np.dtype('U8'), np.dtype('U2'), np.dtype('U2')], usecols=range(1, len(h)), converters={1: col1_converter, 2: col2_converter, 3: col3_converter}, deletechars='', ) print() print(a)
打印输出
col1_converter v = b'1' col2_converter v = b'1' col3_converter v = b'1' col1_converter v = b'"Cell.1"' col1_converter v = b'"Cell.2"' col1_converter v = b'"Cell.3"' col1_converter v = b'"Cell.4"' col1_converter v = b'"Cell.5"' col1_converter v = b'"Cell.6"' col2_converter v = b'NA' col2_converter v = b'NA' col2_converter v = b'1' col2_converter v = b'NA' col2_converter v = b'NA' col2_converter v = b'1' col3_converter v = b'1' col3_converter v = b'NA' col3_converter v = b'NA' col3_converter v = b'NA' col3_converter v = b'NA' col3_converter v = b'NA' [('"Cell.1"', 'NA', '1') ('"Cell.2"', 'NA', 'NA') ('"Cell.3"', '1', 'NA') ('"Cell.4"', 'NA', 'NA') ('"Cell.5"', 'NA', 'NA') ('"Cell.6"', '1', 'NA')]
解答
这是np.genfromtxt的内部类型推断机制导致的:
类型嗅探过程:即使你手动指定了
dtype,np.genfromtxt仍然会读取一行样本数据(默认是表头后的第一行)来验证类型是否合理,这个过程会调用你设置的转换器,但这行样本的这次处理不会被计入最终输出数组。参数不匹配放大了问题:你的代码里存在两个参数不匹配的问题,导致出现了额外的
b'1'输出:dtype的长度是4(对应原始4列),但usecols只选择了3列(原始列1、2、3),这种不匹配会让genfromtxt在处理时出现索引混乱。converters使用了原始列索引(1、2、3),但结合names=True和usecols的设置,这里的索引映射出现了偏差,导致类型嗅探时,把原始列0的"1"(第一行数据的序号列)错误地传递给了三个转换器。
修复方案
- 让
dtype的长度和usecols选择的列数一致,改成dtype=[np.dtype('U8'), np.dtype('U2'), np.dtype('U2')]。 - 改用列名作为
converters的键,避免索引混乱,比如:converters={'Col1': col1_converter, 'Col2': col2_converter, 'Col3': col3_converter}
这样修改后,转换器就只会处理实际的数据行,不会出现额外的b'1'调用记录了。
内容的提问来源于stack exchange,提问作者efthimio
相关产品推荐
相关产品推荐

