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

如何在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")

关键修改说明

  1. 函数移至循环外:避免每次循环重复定义函数,确保变量作用域清晰。
  2. 移除year += 1:外层循环的year变量由range控制,无需手动修改,保证年份从2014到2018完整遍历。
  3. 简化DataFrame处理:直接使用get_day_data返回的DataFrame,避免多余的np.array转换,保留原始列名。
  4. 添加异常捕获:在循环内捕获单天数据处理的错误,避免某一天数据失败导致整个程序终止。
  5. 合并结果并写入Excel:使用pd.concat合并所有收集到的DataFrame,再通过to_excel写入文件,确保所有数据都被保存。

注意事项

  • 确保安装了openpyxl或xlsxwriter(pandas写入Excel需要依赖其中一个库),可以用pip install openpyxl安装。
  • 部分日期可能不存在对应的数据文件,代码会跳过这些日期并打印错误信息,不影响整体流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:51:54