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

Python问题:将get_nav函数输出保存到CSV时仅保留最后一行结果

解决CSV追加API结果仅保留最后一行的问题

你的代码核心问题是每次循环都用to_csv覆盖输出文件,导致之前行的结果被完全替换,最终只剩最后一行的API返回数据。另外,你没有将原CSV的行数据和新获取的指标合并,输出的只是API结果而非完整的原数据+新增列。

以下是两种针对性的解决方案:

方案一:用Pandas实现(更简洁高效)

Pandas其实很适合处理这种批量数据合并,你之前觉得遍历困难是因为没找对方法。完整代码如下:

import pandas as pd

def get_nav(identifiers, asofdate):
    if not isinstance(identifiers, list):
        identifiers = [identifiers]
        
    columns = [
        ["Column", "Expression", "Function", "Parameter", "Display"],
        ["Name",   None,         None,       None,           "Name"],
        ["Height", None,         None,       None,           "Height"],
        ["Weight", None,         None,       None,           "Weight"],
        ["Age",    None,         None,       None,           "Age"],
     ]
    
    options={"asof": asofdate}
    df = thirdparty.apiquery(ids=identifiers, columns=columns, options=options).as_dataframe()
    # 转换为字典,方便按ID匹配提取指标
    result_dict = df.set_index('Name').to_dict('index')
    return result_dict

# 1. 读取原CSV文件到DataFrame
df = pd.read_csv("data.csv")

# 2. 遍历每一行,获取API数据并合并到原DataFrame
for idx, row in df.iterrows():
    id_num = row['IDnumber']
    date = row['Date']
    nav_result = get_nav(id_num, date)
    # 将指标赋值到对应行的新列
    if id_num in nav_result:
        df.loc[idx, 'Height'] = nav_result[id_num]['Height']
        df.loc[idx, 'Weight'] = nav_result[id_num]['Weight']
        df.loc[idx, 'Age'] = nav_result[id_num]['Age']

# 3. 保存完整的结果到CSV(建议输出到新文件,避免覆盖原数据)
df.to_csv(r'F:\backup\holding\Access\Runs\updated_data.csv', index=False)

关键改进点:

  • 一次性读取原文件到DataFrame,避免重复IO操作
  • 遍历行时直接在原DataFrame上追加新列数据
  • 最后一次性写入完整数据,不会覆盖之前内容
  • 调整get_nav的返回格式,更方便按ID匹配提取指标

方案二:用CSV模块实现(符合你当前的遍历思路)

如果你更倾向于用csv模块,需要先收集所有处理后的行,再一次性写入:

import csv

def get_nav(identifiers, asofdate):
    if not isinstance(identifiers, list):
        identifiers = [identifiers]
        
    columns = [
        ["Column", "Expression", "Function", "Parameter", "Display"],
        ["Name",   None,         None,       None,           "Name"],
        ["Height", None,         None,       None,           "Height"],
        ["Weight", None,         None,       None,           "Weight"],
        ["Age",    None,         None,       None,           "Age"],
     ]
    
    options={"asof": asofdate}
    df = thirdparty.apiquery(ids=identifiers, columns=columns, options=options).as_dataframe()
    records = df.to_dict('records')
    return {rec['Name']: rec for rec in records}

# 1. 读取原文件的所有数据并处理
input_file = "data.csv"
output_file = r'F:\backup\holding\Access\Runs\updated_data.csv'

processed_rows = []
with open(input_file, 'r', newline='') as f:
    reader = csv.DictReader(f)
    # 新增三个列名到原表头
    fieldnames = reader.fieldnames + ['Height', 'Weight', 'Age']
    processed_rows.append(fieldnames)
    
    for row in reader:
        id_num = row['IDnumber']
        date = row['Date']
        results = get_nav(id_num, date)
        # 合并原行数据和新指标
        if id_num in results:
            row['Height'] = results[id_num]['Height']
            row['Weight'] = results[id_num]['Weight']
            row['Age'] = results[id_num]['Age']
        else:
            # 处理API返回为空的情况,可设为空字符串或NaN
            row['Height'] = ''
            row['Weight'] = ''
            row['Age'] = ''
        # 按表头顺序整理行数据
        processed_row = [row[field] for field in fieldnames]
        processed_rows.append(processed_row)

# 2. 一次性写入所有处理后的行
with open(output_file, 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(processed_rows)

关键改进点:

  • 先收集所有处理后的行数据,最后一次性写入,避免覆盖
  • 扩展原表头,新增三个指标列
  • 确保原行数据和新指标对应合并,保留所有原列内容

注意事项:

  • 建议输出到新文件(比如updated_data.csv),避免覆盖原数据导致丢失
  • 如果API支持批量查询,可以考虑一次性传入多个ID,减少API调用次数,提升效率
  • 处理API可能返回空的情况,避免触发KeyError

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:35:20