You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:Pandas DataFrame写入CSV仅保留最后一行的问题

解决CSV写入仅保留最后一行及追加异常的问题

看起来你遇到的问题核心在于每次循环都覆盖了之前的CSV内容,而改用mode='a'后又因为重复写入表头或者不必要的合并操作导致异常。咱们一步步来拆解问题,然后给出修复方案:

问题根源分析

你的代码在循环里做了这些多余且导致问题的操作:

  • 每次循环都创建一个仅包含当前行数据的tempDF和df,然后调用to_csv时默认用mode='w'(覆盖模式),所以之前的内容都会被清除,最后只剩最后一行。
  • 循环里的concat操作完全没必要——你每次只处理单条数据,根本不需要合并DataFrame,这只会增加复杂度。
  • 如果直接加mode='a',每次循环都会写入表头,导致CSV里重复出现表头行,这就是你说的“异常输出”。

修复方案(推荐高效写法)

最好的做法是先收集所有数据到列表,最后一次性写入CSV,这样既减少IO操作,也避免覆盖或重复表头的问题:

import pandas as pd
import requests
import json
from datetime import datetime, timedelta

# 文件路径
output_high_csv = r"C:\wab\outputempbeets1.csv"
csvdata = "你的输入CSV路径"  # 注意:原代码中csvdata变量需要补充定义

# 初始化会话
se_ = requests.Session()

# 读取输入CSV,提取需要的列
df = pd.read_csv(csvdata)
df = df[['lat', 'lon', 'field id']]

# 获取昨日日期
dayVal = datetime.strftime(datetime.now() - timedelta(1), '%Y-%m-%d')

# 初始化一个空列表,用来存储所有结果数据
results = []

# 遍历每一行的经纬度和field id
for latrow, lonrow, field_id in zip(df['lat'], df['lon'], df['field id']):
    # 构造API请求URL(原代码中的&是HTML转义,替换为普通&)
    url = f'https://insight.api.wdtinc.com/daily-high-temperature/{latrow}/{lonrow}?start={dayVal}T00:00:00Z&end={dayVal}T01:00:00Z&unit=fahrenheit'
    
    try:
        # 发送请求并捕获HTTP错误
        r = se_.get(url, auth=('USERNAME', 'PASSWORD'), timeout=10)
        r.raise_for_status()
        
        # 解析温度数据
        hi_temp = json.loads(r.content)['series'][0]['value']
        
        # 将当前行的数据添加到结果列表
        results.append({
            'field id': field_id,
            'high temperature': hi_temp
        })
    except Exception as e:
        print(f"处理field id {field_id}时出错: {e}")
        # 可选择跳过错误行,或记录错误信息到日志

# 将结果列表转为DataFrame并写入CSV
if results:
    result_df = pd.DataFrame(results, columns=['field id', 'high temperature'])
    result_df.to_csv(output_high_csv, encoding='utf-8', index=False)
    print("数据写入完成!")
else:
    print("没有有效数据可写入!")

如果你坚持要追加写入(适合数据量极大的场景)

如果数据量非常大,不想一次性加载到内存,可以用追加模式,但要控制表头只写一次:

import pandas as pd
import requests
import json
from datetime import datetime, timedelta
import os

output_high_csv = r"C:\wab\outputempbeets1.csv"
csvdata = "你的输入CSV路径"

se_ = requests.Session()
df = pd.read_csv(csvdata)
df = df[['lat', 'lon', 'field id']]
dayVal = datetime.strftime(datetime.now() - timedelta(1), '%Y-%m-%d')

# 检查文件是否存在,决定是否写入表头
write_header = not os.path.exists(output_high_csv)

for latrow, lonrow, field_id in zip(df['lat'], df['lon'], df['field id']):
    url = f'https://insight.api.wdtinc.com/daily-high-temperature/{latrow}/{lonrow}?start={dayVal}T00:00:00Z&end={dayVal}T01:00:00Z&unit=fahrenheit'
    try:
        r = se_.get(url, auth=('USERNAME', 'PASSWORD'), timeout=10)
        r.raise_for_status()
        hi_temp = json.loads(r.content)['series'][0]['value']
        
        # 创建单条数据的DataFrame
        temp_df = pd.DataFrame([{
            'field id': field_id,
            'high temperature': hi_temp
        }])
        
        # 追加写入,仅第一次写表头
        temp_df.to_csv(output_high_csv, encoding='utf-8', index=False, mode='a', header=write_header)
        
        # 写完第一次后,后续不再写表头
        write_header = False
    except Exception as e:
        print(f"处理field id {field_id}时出错: {e}")

额外优化点

  • 原代码里的dfText = df.astype(basestring)没必要,Pandas可以直接遍历列数据,不需要转成列表再处理。
  • 原URL中的&是HTML转义字符,会导致API参数解析错误,替换为普通&即可。
  • 添加了异常处理,避免某一行出错导致整个程序崩溃,同时方便排查问题。

内容的提问来源于stack exchange,提问作者gwest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:35:36