如何在Python Pandas中扩展DataFrame生成每月1-31日的虚拟日期
解决Pandas扩展DataFrame生成每月1-31日日期行的问题
步骤说明与代码实现
针对需求,可通过以下步骤实现:
清理原始数据,保留唯一的id-年月属性组合
由于同一id在同一月份的nps、target、nps_score字段值一致,先按id和年月分组,提取每组的唯一属性行。为每个年月生成1-31日的日期列表
不管月份实际天数,直接生成该年月的1到31日日期字符串,确保保留所有日期行。展开日期列表并过滤目标范围
将日期列表拆分为多行,再过滤掉不在2022-07-01至2023-10-31范围内的行。
完整代码如下:
import pandas as pd # 原始数据 data = { 'id': [1, 1, 2, 2, 3], 'nps': [8, 8, 7, 7, 5], 'target': [True, True, False, False, True], 'nps_score': [0.56, 0.56, 0.6785, 0.6785, 0.44], 'event_day': ['2023-02-15', '2023-02-22', '2023-06-10', '2023-06-20', '2022-02-11'] } df = pd.DataFrame(data) # 转换日期格式,提取年月维度去重 df['event_day'] = pd.to_datetime(df['event_day']) df_unique = df.groupby(['id', df['event_day'].dt.to_period('M')])[['nps', 'target', 'nps_score']].first().reset_index() df_unique.rename(columns={'event_day': 'year_month'}, inplace=True) # 生成每个年月的1-31日日期字符串 def generate_daily_dates(period): year, month = period.year, period.month return [f"{year}-{month:02d}-{day:02d}" for day in range(1, 32)] df_unique['event_day'] = df_unique['year_month'].apply(generate_daily_dates) # 展开日期列表并清理冗余列 df_expanded = df_unique.explode('event_day').drop(columns='year_month') # 过滤目标日期范围 start_bound = '2022-07-01' end_bound = '2023-10-31' df_final = df_expanded[(df_expanded['event_day'] >= start_bound) & (df_expanded['event_day'] <= end_bound)] # 查看id=1的前5行结果示例 print(df_final[df_final['id'] == 1].head())
结果说明
- 运行后,
df_final即为扩展后的DataFrame,每个id对应月份的1-31日都有一行数据,且保留对应的属性值。 - 原始数据中id=3的2022-02月份不在目标范围内,该行生成的所有日期都会被过滤。
内容的提问来源于stack exchange,提问作者dingaro
相关产品推荐
相关产品推荐

