如何用Pandas高效筛选每月第2天的数据?无需循环或Lambda
解决方案:筛选Pandas数据中每月目标记录
场景1:匹配你的预期结果(取每月数据中的第2条记录)
根据你给出的预期结果,实际需求是按年份-月份分组后,提取每组的第2条记录(索引从0开始计数),无需循环或lambda的高效实现如下:
import pandas as pd # 按年份和月份分组,取每组的第2条记录(nth(1)对应第2条) result = df.groupby([df.index.year, df.index.month]).nth(1) # 若需保留原日期索引格式,可重置后重新设置索引 result = result.reset_index().set_index('date')
执行后得到的结果与你的预期完全一致:
value date 2010-10-02 200 2012-10-03 200 2022-10-04 600
场景2:筛选每月的第2个工作日(匹配你尝试的代码逻辑)
如果你确实需要筛选每月的第2个工作日(不管数据中是否存在该月的更早日期),可以通过生成目标工作日集合再筛选的方式实现:
import pandas as pd from pandas.tseries.offsets import BMonthBegin, BDay # 获取数据覆盖的所有月份 min_month = df.index.min().to_period('M') max_month = df.index.max().to_period('M') all_months = pd.period_range(min_month, max_month, freq='M') # 计算每个月的第2个工作日:当月首个工作日 + 1个工作日 second_business_days = pd.to_datetime([ (month.start_time + BMonthBegin(0) + BDay(1)).date() for month in all_months ]) # 筛选数据中存在目标工作日的行 result = df[df.index.isin(second_business_days)]
原代码未生效的原因
你之前的代码df[df.index == df.index + BMonthBegin(0) + BDay(1)]逻辑有误:
df.index + BMonthBegin(0)是给每个日期加上当月的营业月初,这会把所有日期都转为当月首个工作日,再加1个工作日得到当月第1个工作日;- 用原索引和这个值比较,只有当原日期正好是当月第1个工作日时才会匹配,完全不符合你要筛选第2条记录或第2个工作日的需求。
内容的提问来源于stack exchange,提问作者mike01010
相关产品推荐
相关产品推荐

