如何将CSV读取的字典数组从字符串转为浮点型?
解决CSV存储字典(含浮点数组)后读取类型转换失败的问题
首先得指出你代码里的一个明显问题:你的字典里重复使用了c_y作为键,Python字典的键是唯一的,后面的赋值会直接覆盖前面的,所以最终写入CSV的只有最后一个c_y: ch4_y,其他ch1_y、ch3_y的数据都会丢失。先把键改成唯一的,比如c_y1、c_y3、c_y4。
接下来分析为什么转换会失败:CSV是纯文本格式,当你把numpy数组(从报错信息里的[-2.8000e-07 ...]格式来看,你应该用的是numpy数组)直接写入CSV时,它会被自动转换成带省略号的字符串表示。读取后你拿到的是这个字符串,自然没法用float()直接转换——它本来就不是单个浮点数值的字符串,而是整个数组的文本描述。
下面给你几个可行的解决方案,按推荐程度排序:
方案1:用Pickle直接序列化Python对象(最推荐)
Pickle是Python原生的序列化工具,可以直接保存和恢复几乎所有Python对象,包括numpy数组,不需要手动处理类型转换。
写入代码
import pickle # 修正重复键后的字典 my_dict = { 'c_x': ch1_x, 'c_y1': ch1_y, 'c_y3': ch3_y, 'c_y4': ch4_y, 't': t_fp, 'dt': dt } # 写入二进制文件 with open("path/data.pkl", 'wb') as f: pickle.dump(my_dict, f)
读取代码
import pickle with open("path/data.pkl", 'rb') as f: mydict = pickle.load(f) # 验证类型:数组还是numpy.ndarray,单个值还是float print(type(mydict['c_x'])) # <class 'numpy.ndarray'> print(type(mydict['t'])) # <class 'float'>
方案2:用Joblib处理大数组(适合数据量大的场景)
如果你的浮点数组非常大,Joblib比Pickle的效率更高,专门优化了numpy数组的存储,用法和Pickle几乎一致:
写入代码
from joblib import dump dump(my_dict, "path/data.joblib")
读取代码
from joblib import load mydict = load("path/data.joblib")
方案3:一定要用CSV?手动处理数组序列化(不推荐)
如果因为某些限制必须用CSV,那需要手动把数组转换成可解析的字符串,读取时再还原:
写入代码(把数组转成逗号分隔的字符串)
import csv # 把数组转换成逗号分隔的字符串,单个浮点数转成字符串 my_dict = { 'c_x': ','.join(map(str, ch1_x)), 'c_y1': ','.join(map(str, ch1_y)), 'c_y3': ','.join(map(str, ch3_y)), 'c_y4': ','.join(map(str, ch4_y)), 't': str(t_fp), 'dt': str(dt) } with open("path/dict.csv", 'w') as csv_file: writer = csv.writer(csv_file) for key, value in my_dict.items(): writer.writerow([key, value])
读取代码(还原数组和浮点数)
import csv import numpy as np mydict = {} with open("path/dict.csv") as csv_file: reader = csv.reader(csv_file) for key, value in reader: # 通过逗号判断是否是数组(注意:如果你的浮点数用逗号做小数点分隔符,这个逻辑会失效) if ',' in value: # 拆分字符串并转换为numpy数组 mydict[key] = np.array([float(x.strip()) for x in value.split(',')]) else: # 转换为单个浮点数 mydict[key] = float(value)
这个方法的缺点很明显:如果浮点数的字符串表示里包含逗号(比如部分地区的 locale 设置),判断逻辑会出错;而且如果数组很大,CSV文件会变得非常臃肿,读写效率远不如Pickle/Joblib。
内容的提问来源于stack exchange,提问作者dfs
相关产品推荐
相关产品推荐

