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

如何在for循环中为空Pandas DataFrame迭代添加带索引的值

问题分析与修复方案

核心问题:数据存储逻辑错误

你的代码里dT_dt['dT/dt'] = slope这行是把整个列都替换成当前循环的slope,所以最后所有行都会是最后一次循环计算的结果,而不是对应日期存储。

其他潜在问题

  1. 日期匹配用字符串拼接,不仅繁琐,还容易因为格式问题(比如单双位数的月/日)匹配失败,而且处理Series转字符串的冗余内容(removeprefix/removesuffix)很脆弱。
  2. 每次循环都重复转换raw_data['valid']为datetime,完全没必要,提前做一次就行。
  3. 循环内定义nearest函数,会重复创建函数,浪费资源。
  4. 循环day从1到31,但像2月、4月等没有31天的月份,会找不到对应日期的日出日落数据,直接报错。

修复后的代码

import pandas as pd
from scipy import stats
from datetime import datetime

# ---------------------- 提前完成准备工作 ----------------------
# 1. 提前转换raw_data的时间列,避免循环内重复操作
raw_data['valid'] = pd.to_datetime(raw_data['valid'], format='%m/%d/%Y %H:%M')

# 2. 把sunrise_sunset的Date列转成datetime类型,匹配更可靠
sunrise_sunset['Date'] = pd.to_datetime(sunrise_sunset['Date'], format='%m/%d/%Y')

# 3. 将nearest函数移到循环外,仅定义一次
def nearest(items, pivot):
    return min(items, key=lambda x: abs(x - pivot))

# ---------------------- 初始化存储结构 ----------------------
# 用字典暂存日期与对应slope,最后转DataFrame更高效
dT_dt_dict = {}

# ---------------------- 循环处理每个日期 ----------------------
for month in range(1,13):
    # 根据月份设置最大天数,避免循环无效日期
    if month in [4,6,9,11]:
        max_day = 30
    elif month == 2:
        max_day = 28  # 若需处理闰年可改为29,根据实际数据调整
    else:
        max_day = 31
    
    for day in range(1, max_day+1):
        current_date = datetime(2021, month, day)
        
        # 匹配当日日出日落数据,为空则跳过
        day_data = sunrise_sunset[sunrise_sunset['Date'] == current_date]
        if day_data.empty:
            print(f"无{current_date.strftime('%m/%d/%Y')}的日出日落数据,跳过")
            continue
        
        sunrise_time_str = day_data['Sunrise'].iloc[0]
        sunset_time_str = day_data['Sunset'].iloc[0]
        
        # 转换为完整datetime对象
        sunrise_time = datetime.strptime(f"{current_date.strftime('%m/%d/%Y')} {sunrise_time_str}", "%m/%d/%Y %I:%M:%S %p")
        sunset_time = datetime.strptime(f"{current_date.strftime('%m/%d/%Y')} {sunset_time_str}", "%m/%d/%Y %I:%M:%S %p")
        
        # 查找最近的ASOS时间索引
        valid_times = raw_data['valid'].tolist()
        nearest_sunrise = nearest(valid_times, sunrise_time)
        raw_sunrise_index_time = raw_data[raw_data['valid'] == nearest_sunrise].index[0]
        
        nearest_sunset = nearest(valid_times, sunset_time)
        raw_sunset_index_time = raw_data[raw_data['valid'] == nearest_sunset].index[0]
        
        # 提取当日温度数据并计算斜率
        raw_data_day = raw_data.iloc[raw_sunrise_index_time+2:raw_sunset_index_time]
        raw_t = raw_data_day['tmpf']
        
        raw_t_values = raw_t.astype(float).values
        raw_t_index = raw_t.index.astype(float).values
        slope, _, _, _, _ = stats.linregress(raw_t_index, raw_t_values)
        
        # 将日期和slope存入字典,日期格式转为需求样式
        dT_dt_dict[current_date.strftime('%m/%d/%Y')] = slope

# 将字典转为目标DataFrame,设置索引与列名
dT_dt = pd.DataFrame.from_dict(dT_dt_dict, orient='index', columns=['dT/dt'])
dT_dt.index.name = 'Date'

关键改动说明

  1. 存储逻辑修正:用字典先收集所有日期的slope,最后一次性转成DataFrame,避免循环中覆盖整列的问题,同时提升性能。
  2. 日期处理优化:用datetime类型匹配数据,避免字符串拼接的错误,同时处理不同月份的最大天数,防止无效日期报错。
  3. 性能与容错:提前转换时间列、复用函数,增加空数据判断,减少无效操作与报错风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:39:17