numpy.loadtxt读取CSV空单元格触发ValueError的原因及解决方法
问题描述
我有两组以纬度/经度形式存储在CSV文件中的地理定位数据:第0、1列是第一组的经纬度(约100条),第2、3列是第二组的经纬度(约75条)。尝试将两组数据绘制在同一张图上时,用numpy.loadtxt加载第一组数据正常,但加载第二组时触发如下错误:
ValueError: could not convert string to float: ''
经排查,Python会读取第二组数据中的空白单元格以匹配第一组的行数,进而因无法将空字符串转为浮点数报错。
复现步骤
- 构造CSV文件:前两列填充10条数据,后两列填充不超过9条数据
- 运行以下代码:
import numpy as np import matplotlib.pyplot as plt lat1 = np.loadtxt(r'C:\Users\XXXXX\Desktop\latlong.csv', usecols=0, delimiter=',') long1 = np.loadtxt(r'C:\Users\XXXXX\Desktop\latlong.csv', usecols=1, delimiter=',') lat2 = np.loadtxt(r'C:\Users\XXXXX\Desktop\latlong.csv', usecols=2, delimiter=',') long2 = np.loadtxt(r'C:\Users\XXXXX\Desktop\latlong.csv', usecols=3, delimiter=',') plt.plot(lat1, long1, 'o') plt.plot(lat2, long2, '+')
会触发报错:
Traceback (most recent call last): File "C:\Users\XXXXX\AppData\Local\Programs\Spyder\pkgs\spyder_kernels\py3compat.py", line 356, in compat_exec exec(code, globals, locals) File "c:\users\XXXXX\XXXXX\XXXXX\XXXXX\XXXXX\untitled0.py", line 11, in <module> lat1 = np.loadtxt(r'C:\Users\XXXXX\Desktop\latlong.csv', usecols=0, delimiter=',') File "C:\Users\XXXXX\AppData\Local\Programs\Spyder\pkgs\numpy\lib\npyio.py", line 1163, in loadtxt chunk.append(packer(convert_row(words))) File "C:\Users\XXXXX\AppData\Local\Programs\Spyder\pkgs\numpy\lib\npyio.py", line 1142, in convert_row return [*map(_conv, vals)] File "C:\Users\XXXXX\AppData\Local\Programs\Spyder\pkgs\numpy\lib\npyio.py", line 725, in _floatconv return float(x) # The fastest path. ValueError: could not convert string to float: ''
数据样本
41.878 -93.0977 43.78444 -88.7879 44.062 -114.742 38.58763 -80.4549 40.63313 -89.3985 43.07597 -107.29 40.55122 -85.6024 39.0119 -98.4842
错误原因
numpy.loadtxt会严格按照文件的总行数读取指定列的数据。当某一行的目标列没有数据时,它会将该位置识别为空字符串'',而空字符串无法转换为浮点数,因此触发ValueError。在你的CSV文件中,后两行只有前两列数据,第2、3列是空值,loadtxt读取这些空值时就会报错。
解决方法
以下是几种可行的解决方案:
方案1:使用numpy.genfromtxt处理缺失值
genfromtxt支持自动识别并处理缺失值,可将空值替换为NaN,之后再过滤掉无效值:
import numpy as np import matplotlib.pyplot as plt # 加载数据,将空值填充为NaN data = np.genfromtxt(r'C:\Users\XXXXX\Desktop\latlong.csv', delimiter=',', missing_values='', filling_values=np.nan) # 提取有效数据(过滤NaN) lat1 = data[:, 0][~np.isnan(data[:, 0])] long1 = data[:, 1][~np.isnan(data[:, 1])] lat2 = data[:, 2][~np.isnan(data[:, 2])] long2 = data[:, 3][~np.isnan(data[:, 3])] # 绘图 plt.plot(lat1, long1, 'o') plt.plot(lat2, long2, '+') plt.show()
方案2:用csv模块手动读取并过滤数据
通过逐行读取CSV文件,只提取非空的有效数据:
import csv import matplotlib.pyplot as plt lat1, long1 = [], [] lat2, long2 = [], [] with open(r'C:\Users\XXXXX\Desktop\latlong.csv', 'r') as f: reader = csv.reader(f, delimiter=',') for row in reader: # 处理第一组经纬度(确保列存在且非空) if len(row) >= 2 and row[0].strip() and row[1].strip(): lat1.append(float(row[0].strip())) long1.append(float(row[1].strip())) # 处理第二组经纬度(确保列存在且非空) if len(row) >= 4 and row[2].strip() and row[3].strip(): lat2.append(float(row[2].strip())) long2.append(float(row[3].strip())) # 绘图 plt.plot(lat1, long1, 'o') plt.plot(lat2, long2, '+') plt.show()
方案3:预处理CSV文件
如果数据量不大,可以手动编辑CSV文件,删除第二组数据缺失的行,或者在空白单元格中填入NaN(numpy可以识别NaN为有效浮点数)。
内容的提问来源于stack exchange,提问作者cat_herder
相关产品推荐
相关产品推荐

