np.loadtxt读取字符串时skiprows参数引发意外跳过行的问题
np.loadtxt读取字符串时skiprows参数引发意外跳过行的问题
这个问题其实是numpy的np.loadtxt在处理字符串类型数据时的一个典型小坑,核心原因和它自动推断字符串长度的机制有关,咱们一步步拆解:
问题背后的原理
当你给np.loadtxt指定dtype=str时,它不会直接使用通用的可变长度字符串类型,而是会先扫描文件的前若干行(默认是前100行)来自动推断字符串的最大长度,然后生成对应长度的固定宽度字符串类型(比如U9这种)。这个推断逻辑会因为skiprows参数的使用而改变扫描范围:
- 不使用
skiprows时,扫描范围包含表头和后续数据,自然会碰到那些长度为10的IID,所以能推断出足够容纳所有数据的字符串长度,因此所有行(包括表头)都被正确读取,得到总长度524123。 - 当加上
skiprows=1后,扫描的起始位置变成了第一行数据。如果刚好前100行数据里没有那些长度为10的IID,np.loadtxt就会推断出一个更小的字符串长度(比如U9),这时那些长度为10的字符串就超出了这个宽度,被判定为无效数据直接跳过,最终就少了10行。
而你手动指定dtype='<U20'或'<U10'时,相当于直接告诉numpy要使用足够容纳所有IID的固定宽度,绕过了自动推断的逻辑,所以所有长度10的字符串都能被正确读取,得到了符合预期的524122行。
解决办法
这里有几个可靠的解决方案:
- 手动指定足够大的字符串类型:就像你已经尝试的那样,根据数据的实际长度指定
dtype,比如dtype='<U20',确保能覆盖所有IID的长度。 - 改用
np.genfromtxt:这个函数的字符串处理更灵活,默认会使用可变长度的字符串类型,不会因为自动推断长度的问题丢失数据:len(np.genfromtxt('foo.txt', usecols=0, dtype=str, skip_header=1)) - 升级numpy后调整参数:如果你的numpy版本在1.19及以上,可以结合
encoding参数使用dtype=str,不过相比前两种方法,这个的兼容性稍差。
备注:内容来源于stack exchange,提问作者user2834012
相关产品推荐
相关产品推荐

