使用csv.writer.writerow/writerows添加行时CSV表头/列丢失问题
问题原因
- 缺少表头写入逻辑:你将DataFrame转为numpy数组、逐行取数值列表的操作,不会包含DataFrame的列名信息,最终保存的CSV文件没有表头行。pandas默认会把CSV第一行识别为列名,导致原本的第一行数据被当成表头,有效数据行数直接少1行,所以你两次写入合计500行数据,最终读出来只有499行有效数据。
- 写入模式错误:你当前代码使用的
'w'是覆盖写入模式,会直接清空原有文件内容再写入新数据,根本无法实现追加效果。要追加内容必须改用'a'追加模式。 - 列数不匹配原因:你调用
reset_index()将原本的日期索引转为了普通数据列,原本20列的DataFrame会多出来1列索引列,写入后实际是21列。你读取得到200列大概率是读写时分隔符不统一,比如写入用csv默认的逗号分隔,读取时指定了其他分隔符,或是数据内容包含未转义的逗号导致列被错误拆分。 - 冗余代码问题:
with上下文管理器会自动关闭打开的文件,你手动调用outfile.close()属于冗余操作,没有必要。
解决方案
方案一:使用pandas内置方法(最推荐,无需额外调用csv模块,避免格式不统一)
无需自己实现写入逻辑,直接用pandas自带的to_csv方法即可完美适配需求:
import pandas as pd # 首次保存:写入表头+保留日期索引 data.to_csv("target.csv", index=True) # 追加保存:不写入表头、追加模式写入 data.to_csv("target.csv", index=True, mode="a", header=False) # 读取:指定第一列为索引,直接得到形状为(500, 20)的DataFrame df_read = pd.read_csv("target.csv", index_col=0)
方案二:修改现有csv.writer代码
如果要保留你现有的写入逻辑,调整后代码如下:
import csv def _writeBulk(savefile, data, is_first_write=False): df = data.reset_index() # 首次写入用覆盖模式,后续追加用追加模式 write_mode = "w" if is_first_write else "a" with open(savefile, write_mode, newline="") as outfile: writer = csv.writer(outfile) # 首次写入需要先写入表头 if is_first_write: writer.writerow(df.columns.tolist()) writer.writerows(df.to_numpy().tolist()) # 调用示例 # 第一次写入文件 _writeBulk("target.csv", data, is_first_write=True) # 第二次追加写入 _writeBulk("target.csv", data, is_first_write=False) # 读取时指定第一列为索引 df_read = pd.read_csv("target.csv", index_col=0)
内容的提问来源于stack exchange,提问作者Ji-Mu Kang
相关产品推荐
相关产品推荐

