Python 如何把握季节,如果一个日期范围在美国与熊猫度假?
我有一个pandas数据框架,它有两列,分别命名为date_x和date_y。我想在一个单独的列中提取季节日期x(冬季、春季、夏季或秋季),然后确定某个假日的日期范围是否不包括日期y。我已经看到了一些潜在的解决方案,它们通过将一年分解成几天来完成四季,但我似乎无法让这对我起作用。我还在想熊猫能做什么。我面临的另一个问题是如何解释像复活节这样每年都在变化的假期。非常感谢您的帮助 我也尝试过为自己工作,但不知道如何调整它来创建一个新的专栏,它可以在过时而不是今天的日期工作 下面是我正在努力的一张图片Python 如何把握季节,如果一个日期范围在美国与熊猫度假?,python,pandas,Python,Pandas,我有一个pandas数据框架,它有两列,分别命名为date_x和date_y。我想在一个单独的列中提取季节日期x(冬季、春季、夏季或秋季),然后确定某个假日的日期范围是否不包括日期y。我已经看到了一些潜在的解决方案,它们通过将一年分解成几天来完成四季,但我似乎无法让这对我起作用。我还在想熊猫能做什么。我面临的另一个问题是如何解释像复活节这样每年都在变化的假期。非常感谢您的帮助 我也尝试过为自己工作,但不知道如何调整它来创建一个新的专栏,它可以在过时而不是今天的日期工作 下面是我正在努力的一张图片
我相信您正在寻找下面这样的产品。请注意,此解决方案的一部分使用了提供的答案 您可能需要调整以满足您的独家需求,但这会让您产生想法
将熊猫作为pd导入
将numpy作为np导入
导入假日#pip安装假日
从日期时间导入日期,日期时间
美国假日=假日
Y=2000#允许输入X-02-29(闰日)的虚拟闰年
季节=[(‘冬季’,(日期(Y,1,1),日期(Y,3,20)),
(‘春天’,(日期(Y,3,21),日期(Y,6,20)),
(‘夏季’,(日期(Y,6,21),日期(Y,9,22)),
(‘秋天’,(日期(Y,9,23),日期(Y,12,20)),
(‘冬季’,(日期(Y,12,21),日期(Y,12,31))]
def get_季节(dt):
如果isinstance(dt,日期时间):
dt=dt.日期()
dt=dt.更换(年份=Y)
下一个(一季接一季,(开始,结束)按季返回
如果start将列转换为datetime类型(如果尚未转换),并构造两个新的空列:
df.Date_x = pd.to_datetime(df.Date_x)
df.Date_y = pd.to_datetime(df.Date_y)
一旦注意到datetime Series的quarter
属性,添加季节列就很容易了:
df['Season'] = df.Date_x.dt.quarter.map({1: 'Spring', 2: 'Summer', 3: 'Fall', 4: 'Winter'})
假期显然有点复杂。从一个空列开始:
df['Holiday'] = ''
复活节是一个特别的节日,让我们先来关注它。熊猫有它的内置功能,不过你也可以定义自己的节日规则
easter = df.Date_y - pd.tseries.offsets.Easter()
这就给了你在Date\u y
之前的复活节(我本可以使用Date\u x+Easter()
,但你说你想要它不包括Date\u y
)。然后:
df.loc[df.Date\u x
这会将“复活节”放在假日所在的行中[日期x,日期y)
我把它作为一个练习留给你,让你为剩下的假期创建假期规则。这里有一些建议:假设你有一个数据框,其中的日期不仅包括多个假期,还包括多个季节:
Date_x Date_y
0 2020-12-22 2021-01-01
1 2020-06-20 2020-07-11
3 2020-02-11 2020-03-27
4 2020-05-22 2020-06-27
为了获得1.季节
和2.假日
:
我建立了你共享的链接来定制季节
我试图避免“第三方”图书馆,并选择使用USFederalHolidayCalendar
从pandas
holiday
图书馆获得的USFederalHolidayCalendar;因为,我认为这样更可靠;然而,我对假日图书馆没有太多经验。此外,还有多个日历可以从pandas图书馆使用。从那里,我向我们介绍了它编辑了我创建的get_seasure(x)
和get_holiday()
函数。对于前者,我将引用您问题中的链接,而后者使用列表理解将假日从我创建的holidays
数据框中拉入您的数据框
从pandas.tseries.holiday导入USFederalHolidayCalendar
从日期时间导入日期时间
作为pd进口熊猫
cal=USFederalHolidayCalendar()
假日=(pd.DataFrame(cal.holidays(return\u name=True),columns=['Holiday']))
.reset_index()
.rename({'index':'Date'},axis=1))
假日['Date']=pd.to_datetime(假日['Date'])
df=pd.DataFrame({'Date_x':{0:'2020-12-22',1:'2020-06-20',2:'2020-02-11',3:'2020-05-22'},
“日期:{0:'2021-01-01',1:'2020-07-11',2:'2020-03-27',3:'2020-06-27'})
df['Date\u x']=pd.to\u datetime(df['Date\u x'])
df['Date\u y']=pd.to\u datetime(df['Date\u y'])
Y=2000#允许输入X-02-29(闰日)的虚拟闰年
季节=[(‘冬季’,(日期(Y,1,1),日期(Y,3,20)),
(‘春天’,(日期(Y,3,21),日期(Y,6,20)),
(‘夏季’,(日期(Y,6,21),日期(Y,9,22)),
(‘秋天’,(日期(Y,9,23),日期(Y,12,20)),
(‘冬季’,(日期(Y,12,21),日期(Y,12,31))]
def get_季节(x):
x=x.更换(年份=Y)
下一个(一季接一季,(开始,结束)按季返回
如果开始,这个解决方案最难的部分是Holiday
列输出,但是我认为有一个特定的库用于我们的假期:forgeks.org/python-Holidays-library/Yeah,这也是我的感觉。虽然我不知道有一个Holiday python库,所以它可能会派上用场,但我仍然很难获得函数不过,我不知道这是否有意义。这太棒了,正是我想做的!虽然当我用'df=pd.read_csv('dates.csv')替换您制作的数据框时,我在第23行遇到了一个StopIteration错误:23返回下一季(每季,(开始,结束)在季节中,数据中的空值会导致这种情况吗?@LarryFlores可能会尝试删除这些行,以使用df=df[(df['Date\u x'].notnull())和(df['Date\u y'].notnull())进行测试
是的,这就是问题所在,这实际上是我启动此线程的主要原因,因为我一直认为自己做错了什么。因此,当我看到我在您的示例中遇到相同的错误时,我想可能只是空值。不管怎样,非常感谢您的所有时间、努力和帮助,我真的很感激吃得比你知道的还多。这是我的错
df.loc[df.Date_x < easter, 'Holiday'] = 'Easter'
Date_x Date_y
0 2020-12-22 2021-01-01
1 2020-06-20 2020-07-11
3 2020-02-11 2020-03-27
4 2020-05-22 2020-06-27
from pandas.tseries.holiday import USFederalHolidayCalendar
from datetime import datetime
import pandas as pd
cal = USFederalHolidayCalendar()
holidays = (pd.DataFrame(cal.holidays(return_name=True), columns=['Holiday'])
.reset_index()
.rename({'index': 'Date'}, axis=1))
holidays['Date'] = pd.to_datetime(holidays['Date'])
df= pd.DataFrame({'Date_x': {0: '2020-12-22', 1: '2020-06-20', 2: '2020-02-11', 3: '2020-05-22'},
'Date_y': {0: '2021-01-01', 1: '2020-07-11', 2: '2020-03-27', 3: '2020-06-27'}})
df['Date_x'] = pd.to_datetime(df['Date_x'])
df['Date_y'] = pd.to_datetime(df['Date_y'])
Y = 2000 # dummy leap year to allow input X-02-29 (leap day)
seasons = [('Winter', (date(Y, 1, 1), date(Y, 3, 20))),
('Spring', (date(Y, 3, 21), date(Y, 6, 20))),
('Summer', (date(Y, 6, 21), date(Y, 9, 22))),
('Fall', (date(Y, 9, 23), date(Y, 12, 20))),
('Winter', (date(Y, 12, 21), date(Y, 12, 31)))]
def get_season(x):
x = x.replace(year=Y)
return next(season for season, (start, end) in seasons
if start <= x <= end)
def get_holiday():
return pd.DataFrame([(h,y,z) for (h,d) in zip(holidays['Holiday'], holidays['Date'])
for (y, z) in zip(df['Date_x'], df['Date_y']) if y.date() <= d.date() if d.date() <= z.date()], columns=['Holiday', 'Date_x', 'Date_y'])
s1 = df['Date_x'].apply(lambda x: get_season(x))
s2 = df['Date_y'].apply(lambda x: get_season(x))
df['Season']= [', '.join(list(set([x,y]))) for (x,y) in zip(s1,s2)]
dft = get_holiday()
dft = dft.groupby(['Date_x', 'Date_y'])['Holiday'].apply(lambda x: ', '.join(list(x)))
df = pd.merge(df, dft, how='left', on=['Date_x', 'Date_y'])
df
Out[32]:
Date_x Date_y Season Holiday
0 2020-12-22 2021-01-01 Winter Christmas, New Years Day
1 2020-06-20 2020-07-11 Summer, Spring July 4th
2 2020-02-11 2020-03-27 Spring, Winter Presidents Day
3 2020-05-22 2020-06-27 Summer, Spring Memorial Day