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
相关产品推荐
相关产品推荐

