如何在Pandas中选择“每月最后一个工作日”?

13

我试图按照每月最后一天的条件对数据框进行子集操作。我使用了以下代码:

df['Month_End'] = df.index.is_month_end
sample = df[df['Month_End'] == 1]

这个方法可行,但我正在处理股市数据,所以我错过了所有实际月末在周末的情况,我需要一种选择“月末最后一个工作日”的方法。

3个回答

13

通过传入freq='BM',您可以生成每月最后一个工作日的时间序列

例如,要创建2014年最后一个工作日的系列:

>>> pd.date_range('1/1/2014', periods=12, freq='BM')
[2014-01-31 00:00:00, ..., 2014-12-31 00:00:00]
Length: 12, Freq: BM, Timezone: None

你可以使用这个时间序列来对你的数据框进行子集筛选/重新索引。

2
这个解决方案可行。唯一的问题是,在某些系列中,月份的最后一个工作日可能是“自定义节假日”,所以你需要将其纳入方程。 - hernanavella
我正在使用这个问题中被接受的答案:https://dev59.com/yQn5s4cB2Jgan1znMp1D,但是有没有更好的“子集/重新索引”的方法? - Koray Tugay
1
hernanavella 的评论很关键。我们如何在 Python 中回答这个简单的问题?我们只想要一个干净且易于实现的答案:每月最后一个交易日。 - Jingwei Yu

3

不必生成系列,您还可以从日期时间索引中解析业务月末,如下所示:

df['BMonthEnd'] = (df.index + pd.offsets.BMonthEnd(1)).day

请注意,目前这只会抛出一个无害的警告 - 请参见http://pandas.pydata.org/pandas-docs/stable/timeseries.html#using-offsets-with-series-datetimeindex

注意:如果日期(d)已经是本月的最后一个工作日,则d + pd.offsets.BMonthEnd(1)将给出下个月的最后一个工作日。如果不希望这样,请使用pd.offsets.BMonthEnd(0)代替:

df['BMonthEnd'] = (df.index + pd.offsets.BMonthEnd(0)).day

编辑: 根据OP的要求,实际上要对df进行过滤:
df = df[(df.index + pd.offsets.BMonthEnd(0)).day == df.index.day]

1
请注意,此方法并非完美。如果某天“d”是该月的最后一个工作日,则d+BMonthEnd(1)将给出下个月的最后一个工作日。 - g.a

0

这是用于从给定索引为日期时间类型的DataFrame对象中筛选出每个月的最后一个工作日的代码。
df.resample('BM').mean()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接