如何按每月15日或最近工作日筛选DataFrame记录?
筛选每月最接近15日的工作日记录
需求说明
需要从仅包含工作日的DataFrame中,筛选出每月15日的记录;若当月无15日数据,则选择最接近15日的记录(示例中优先选择15日之前最近的记录)。
数据示例:
date open date1 date2 0 2000-01-03 00:00:00 0 2000-01-17 00:00:00 2000-02-15 00:00:00 1 2000-01-07 00:00:00 6084704 2000-01-17 00:00:00 2000-02-15 00:00:00 3 2000-01-12 00:00:00 992482 2000-01-17 00:00:00 2000-02-15 00:00:00 4 2000-01-17 00:00:00 11721104 2000-02-15 00:00:00 2000-03-15 00:00:00 ...
预期结果示例:
3 2000-01-12 00:00:00 992482 2000-01-17 00:00:00 2000-02-15 00:00:00 ... 61 2000-04-13 00:00:00 17913960 2000-05-15 00:00:00 2000-06-15 00:00:00 ...
解决方案
步骤1:确保日期列是datetime类型
如果date列还不是datetime格式,先转换:
import pandas as pd df['date'] = pd.to_datetime(df['date'])
步骤2:计算每条记录与当月15日的天数差
创建辅助列,计算日期与当月15日的天数差绝对值;如果需要优先选择15日之前的记录,给15日之后的记录加微小权重,保证差值相同时更早的记录被选中:
# 生成当月15日的datetime对象 df['month_15'] = df['date'].apply(lambda x: x.replace(day=15)) # 计算天数差,15日之后的记录差值加0.1,确保优先选15日前的记录 df['day_diff'] = abs(df['date'] - df['month_15']).dt.days + (df['date'] > df['month_15']).astype(int)*0.1
步骤3:按年-月分组,筛选最优记录
按年份和月份分组,每组选择day_diff最小的行:
# 分组取最小差值的记录 result_df = df.groupby([df['date'].dt.year, df['date'].dt.month]).apply(lambda x: x.loc[x['day_diff'].idxmin()]) # 重置索引(可选,根据需求调整) result_df = result_df.reset_index(drop=True)
简化版链式代码
如果不需要保留辅助列,可以合并为一行链式调用:
import pandas as pd df['date'] = pd.to_datetime(df['date']) result_df = (df.assign( month_15=lambda x: x['date'].apply(lambda d: d.replace(day=15)), day_diff=lambda x: abs(x['date'] - x['month_15']).dt.days + (x['date'] > x['month_15']).astype(int)*0.1 ) .groupby([df['date'].dt.year, df['date'].dt.month]) .apply(lambda g: g.loc[g['day_diff'].idxmin()]) .reset_index(drop=True))
可选调整
- 如果不需要优先选择15日之前的记录,去掉
+ (df['date'] > df['month_15']).astype(int)*0.1即可,此时会选择距离15日天数最少的记录(无论前后)。 - 若同一月份有多个记录与15日天数差相同(比如14日和16日),
idxmin()会返回第一个出现的最小值索引,即最早的记录。
内容的提问来源于stack exchange,提问作者bella
相关产品推荐
相关产品推荐

