Python读写含数字列表列的CSV时列表类型丢失问题求助
Python读写含数字列表列的CSV时列表类型丢失问题求助
这个问题我之前也踩过一模一样的坑!本质原因很简单:CSV是纯文本格式,它根本没法原生识别Python里的列表类型——当你用to_csv保存DataFrame时,列表会被直接转成字符串(比如原本的[-2, 3, 5]会变成"[-2, 3, 5]"),而read_csv读取时只会把它当成普通字符串处理,不会自动帮你转回数字列表,所以之后用[0]取到的就是字符串的第一个字符了。
给你几个实用的解决办法,按需选择:
方法1:读CSV时用转换器解析字符串为列表
这是最直接适配CSV的方案,关键在读的时候把字符串转回数字列表,推荐用ast.literal_eval(比原生eval安全很多,不会执行恶意代码):
import ast import pandas as pd # 定义解析函数,把字符串转回数字列表 def parse_num_list(s): try: # 解析字符串为Python字面量(这里就是列表) return ast.literal_eval(s) except (ValueError, SyntaxError): # 处理空值或格式异常的情况,返回空列表或原内容 return [] # 读取时给Seq_1和Seq_2列指定转换器 df = pd.read_csv( "../data/df.csv", low_memory=False, converters={"Seq_1": parse_num_list, "Seq_2": parse_num_list} ) # 保存时还是用原来的to_csv就行 df.to_csv("../data/df.csv", index=False)
用这个方法后,你再调用df.loc[0].Seq_1[0]就能得到原本的-2了。
方法2:用支持保留类型的格式替代CSV
如果不需要兼容非Python的工具,更推荐用Pickle、Parquet或Feather这类专门为Python数据设计的格式,它们能完整保留DataFrame的所有类型信息,不需要手动转换:
用Pickle(最简单,Python原生)
# 保存 df.to_pickle("../data/df.pkl") # 读取 df = pd.read_pickle("../data/df.pkl")
用Parquet(更适合大数据,跨语言兼容)
需要先安装依赖:pip install pyarrow
# 保存 df.to_parquet("../data/df.parquet", index=False) # 读取 df = pd.read_parquet("../data/df.parquet")
这种方法不仅能完美保留列表类型,读写速度也比CSV快很多,数据体积通常也更小。
方法3:自定义列表的CSV存储格式(适合特殊场景)
如果必须用CSV,且担心ast.literal_eval的兼容性(比如列表字符串里有特殊符号),可以在保存前把列表转成自定义分隔的字符串,比如用分号分隔数字:
# 保存前:把列表转成分号连接的字符串 df["Seq_1"] = df["Seq_1"].apply(lambda x: ";".join(map(str, x))) df["Seq_2"] = df["Seq_2"].apply(lambda x: ";".join(map(str, x))) df.to_csv("../data/df.csv", index=False) # 读取时:拆分字符串并转成数字列表 def parse_custom_sep_list(s): return list(map(float, s.split(";"))) df = pd.read_csv( "../data/df.csv", low_memory=False, converters={"Seq_1": parse_custom_sep_list, "Seq_2": parse_custom_sep_list} )
这个方法更可控,完全避免了列表转字符串时的方括号、逗号干扰。
备注:内容来源于stack exchange,提问作者Coleman YU
相关产品推荐
相关产品推荐

