如何在Python中将while循环迭代的所有结果保存至Excel文件?
问题分析与修复方案
核心问题
你的代码存在几个关键错误,导致无法收集所有迭代结果:
- 函数
get_day_data定义在三层循环内部,每次循环都会重新定义函数,引发作用域混乱。 - 循环内部修改了外层循环的
year变量(year += 1),直接打乱了原有的年份遍历逻辑,导致循环提前终止。 - 对
get_day_data返回的DataFrame做了多余的转换(pd.DataFrame(np.array(...))),丢失了列名且可能引发数据结构问题。 - 最终未将收集到的所有DataFrame合并并写入Excel。
修复后的完整代码
import urllib.request import datetime as dt from datetime import datetime, timezone, tzinfo import cdflib import numpy as np import pandas as pd from cdflib.epochs import CDFepoch import pathlib # 将函数移到循环外部,避免重复定义 def get_day_data(station: str, year, month, day): is_pg = station.startswith("pg") if is_pg: url = f"http://mist.nianet.org/CDFdata/{station}/{year}/thg_l2_mag_{station}_{year}{month}{day}_v01.cdf" else: url = f"https://ftp.space.dtu.dk/data/Ground_magnetometers/Adjusted/{station.upper()}/{year}/{month}/{station.upper()}_{year}{month}{day}.cdf" file_name = url.split("/")[-1] if not pathlib.Path(file_name).exists(): try: urllib.request.urlretrieve(url, "tmp.cdf") pathlib.Path("tmp.cdf").rename(file_name) except: raise Exception(f"Failed to download {url}") cdf = cdflib.CDF(file_name) if is_pg: epoch = cdf.varget(f"thg_mag_{station}_time") index = pd.to_datetime(epoch, utc=False, unit="s") variable = f"thg_mag_{station}" else: epoch = cdf.varget("time") epoch = CDFepoch().to_datetime(epoch, to_np=True) index = pd.to_datetime(epoch) variable = "HEZ" values = cdf.varget(variable) if "FILLVAL" in cdf.varattsget(variable): values[values == cdf.attget("FILLVAL", variable)["Data"]] = np.nan if "VALIDMIN" in cdf.varattsget(variable): values[values < cdf.attget("VALIDMIN", variable)["Data"]] = np.nan if "VALIDMAX" in cdf.varattsget(variable): values[values > cdf.attget("VALIDMAX", variable)["Data"]] = np.nan return pd.DataFrame({ "epoch": index, "X": values[:, 0], "Y": values[:, 1], "Z": values[:, 2] }) result = [] months = ['01','02','03','04','05','06','07','08','09','10','11','12'] days = ['01','02','03','04','05','06','07','08','09','10','11','12'] # 移除循环内的year修改,保持外层循环的年份遍历逻辑 for year in range(2014,2019,1): for month_str in months: for day_str in days: try: # 直接使用函数返回的DataFrame,无需多余转换 daily_data = get_day_data('pg0', year, month_str, day_str) result.append(daily_data) print(f"已收集 {year}-{month_str}-{day_str} 的数据") except Exception as e: print(f"处理 {year}-{month_str}-{day_str} 时出错: {e}") continue # 合并所有DataFrame all_data = pd.concat(result, ignore_index=True) # 写入Excel文件 all_data.to_excel("magnetometer_data.xlsx", index=False) print("所有数据已成功保存到 magnetometer_data.xlsx")
关键修改说明
- 函数移至循环外:避免每次循环重复定义函数,确保变量作用域清晰。
- 移除
year += 1:外层循环的year变量由range控制,无需手动修改,保证年份从2014到2018完整遍历。 - 简化DataFrame处理:直接使用
get_day_data返回的DataFrame,避免多余的np.array转换,保留原始列名。 - 添加异常捕获:在循环内捕获单天数据处理的错误,避免某一天数据失败导致整个程序终止。
- 合并结果并写入Excel:使用
pd.concat合并所有收集到的DataFrame,再通过to_excel写入文件,确保所有数据都被保存。
注意事项
- 确保安装了
openpyxl或xlsxwriter(pandas写入Excel需要依赖其中一个库),可以用pip install openpyxl安装。 - 部分日期可能不存在对应的数据文件,代码会跳过这些日期并打印错误信息,不影响整体流程。
内容的提问来源于stack exchange,提问作者serlly Vega
相关产品推荐
相关产品推荐

