python - 有没有办法遍历执行功能的熊猫日期时间系列?
问题描述
我创建了一个描述季节性的自定义函数,并希望通过将该函数应用于 pandas 数据帧中的一系列日期时间对象来向数据帧添加一个新列。我正在尝试创建一个列表,其中包含应用于数据框中日期的 date_season 函数的值。
下面的 date_season 函数中的所有变量都是 datetime.date 类型,但 'dif' 除外,它是一个 datetime.timedelta。
这是功能:
import datetime as dt
import pandas as pd
def date_season(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
x = (((max_season - min_season).days) - dif.days * 2) / (max_season - min_season).days
seasonality = np.sin(x * (np.pi) / 2)
return(seasonality)
以下是 pandas 数据框的创建方式:
start = dt.date(2017,1,1)
end = dt.date(2019,12,31)
df = pd.DataFrame({'Date': pd.date_range(start, end, freq="D")})
尝试使用季节性参数创建一个新列表:
z = []
for index, row in df.iterrows():
z.append(date_season(row.Date))
这将返回错误消息:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-105-63e9cb35ed55> in <module>()
1 z = []
2 for index, row in df.iterrows():
----> 3 z.append(date_season(row.Date))
<ipython-input-71-5e2b35e24e38> in date_season(date)
3 min_season = dt.date(year,1,1)
4 max_season = dt.date(year,6,30)
----> 5 dif = abs(max_season - date)
6 dif_days = dif.days
7 x = (((max_season - min_season).days) - dif.days * 2) / (max_season - min_season).days
pandas\_libs\tslibs\timestamps.pyx in
pandas._libs.tslibs.timestamps._Timestamp.__sub__()
TypeError: descriptor '__sub__' requires a 'datetime.datetime' object but received a 'datetime.date'
尝试:
new_df = df.apply(lambda x: date_season(x))
返回
AttributeError: ("'Series' object has no attribute 'year'", 'occurred at index Date')
不确定为什么它需要 datetime.datetime 对象,因为该函数适用于 datetime.date 格式的单个输入。有没有更简单的方法来遍历日期并使用此函数的结果创建一个新列?
解决方案
您需要将 min_season 和 max_season 定义为 pandas 日期时间对象,而不是内置的 python 日期时间类。这很令人困惑,但它们并不完全可以互换。
def date_season(date):
year = date.year
#use pandas.datetime
min_season = pd.datetime(year,1,1)
max_season = pd.datetime(year,6,30)
dif = abs(max_season - date)
dif_days = dif.days
x = (((max_season - min_season).days) - dif.days * 2) / (max_season - min_season).days
seasonality = np.sin(x * (np.pi) / 2)
return(seasonality)
现在,您可以对整个数据框使用 applymap,也可以在单个列上使用 apply。
new_df = df.applymap(date_season)
或者
df['Date'].apply(date_season)
推荐阅读
- python - 生成具有每个整数出现次数的随机整数数组
- sass - 如何在 Sass 中创建一个空 Map?
- docker-compose - Docker Compose 文件以创建具有多个图像的容器
- r - 使用 dplyr::filter 问题创建 R 函数
- reactjs - 在 ReactJS 的“第 2 页”上启动“3 页”单页网站
- java - Maven 依赖项:列表显示的版本与正在执行的版本不同
- c# - Xamarin.Android 上的可绘制动画
- android-studio - 在 Play 商店进行 beta 测试的 Android Studio 应用
- amazon-web-services - 通过 API-Gateway 调用 Lambda 并给出 403 响应?
- php - 抽出随机数量的问题,例如 04 out of 10