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

如何在Pandas时间序列中迭代执行自定义季节性函数并新增列?

解决Pandas中自定义季节性函数应用于Datetime序列的问题

先帮你拆解下两个报错的原因,再给出更简便的实现方案:

报错原因分析

  1. iterrows()的TypeError:
    你用pd.date_range生成的Date列是Pandas的Timestamp类型,不是Python原生的datetime.date。当你在函数里用dt.date(year,1,1)(原生date对象)和Timestamp做减法时,类型不匹配就会抛出这个错误——原生datetime的__sub__方法只接受同类型的对象。

  2. apply()的AttributeError:
    看起来你应该是直接调用了df.apply(date_season),而不是针对Date列调用df['Date'].apply(date_season)。前者会把整个行的Series传入函数,而Series没有year属性,自然会报错。如果是针对列调用apply,其实只要函数兼容Timestamp类型就可以正常运行。

修正方案:兼容Timestamp的函数+正确apply用法

先修改你的函数,让它能同时处理datetime.date和pd.Timestamp类型:

import datetime as dt
import pandas as pd
import numpy as np

def date_season(date):
    # 把Timestamp转成原生date对象(如果是Timestamp的话)
    if isinstance(date, pd.Timestamp):
        date = date.date()
    year = date.year
    min_season = dt.date(year,1,1)
    max_season = dt.date(year,6,30)
    dif = abs(max_season - date)
    dif_days = dif.days
    total_half_year_days = (max_season - min_season).days
    x = (total_half_year_days - dif_days * 2) / total_half_year_days
    seasonality = np.sin(x * np.pi / 2)
    return seasonality

# 生成数据
start = dt.date(2017,1,1)
end = dt.date(2019,12,31)
df = pd.DataFrame({'Date': pd.date_range(start, end, freq="D")})

# 正确应用函数到Date列
df['Seasonality'] = df['Date'].apply(date_season)

更高效的向量化方案(推荐)

上面的apply是逐元素处理,对于大数据集效率不高。我们可以用Pandas的dt属性做完全向量化的计算,速度会快很多:

# 提取日期的年、日序数、是否闰年
df['dayofyear'] = df['Date'].dt.dayofyear
df['is_leap'] = df['Date'].dt.is_leap_year

# 计算每年6月30日的日序数(平年181,闰年182)
df['june30_day'] = np.where(df['is_leap'], 182, 181)
# 计算距离6月30日的天数
df['dif_days'] = abs(df['june30_day'] - df['dayofyear'])
# 上半年总天数
df['half_year_days'] = df['june30_day']

# 计算x和季节性值
df['x'] = (df['half_year_days'] - df['dif_days'] * 2) / df['half_year_days']
df['Seasonality_vectorized'] = np.sin(df['x'] * np.pi / 2)

这个方案不需要循环或apply,完全利用Pandas和NumPy的向量化运算,性能提升明显,尤其是当你的数据集很大时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:52:49