在Pandas中根据起止日期添加月份天数列遇问题求助
问题:为DataFrame添加日期区间内各月份计数列失败
我在给DataFrame添加基于起止日期的各月份对应计数列时遇到问题,执行代码后保存Excel看不到新增列,无报错信息。
输入数据
df = pd.DataFrame([[01/04/2022, 03/05/2022], [07/04/2022,01/05/2022]], columns=['Contract From', 'Contract To'])
预处理代码
df['Contract To'] = pd.to_datetime(df['Contract To'], dayfirst=True) df['Start Date'] = df['Contract From'] df['End Date'] = df['Contract To'] df['End Date'].fillna("31/03/2023", inplace=True) df['Start Date'] = pd.to_datetime(df['Start Date']) df['End Date'] = pd.to_datetime(df['End Date'])
尝试的代码
res = df.join(df.apply(lambda x: pd.Series(pd.date_range(x['Start Date'], x['End Date'], freq='D').to_period('M')), axis=1).apply(pd.value_counts, axis=1).fillna(0).astype(int))
期望结果
| Start Date | End Date | 2022-04 | 2022-05 | 2022-06 |
|---|---|---|---|---|
| 01/04/2022 | 03/05/2022 | 30 | 3 | 0 |
| 07/04/2022 | 01/05/2022 | 23 | 1 | 0 |
问题原因及解决方案
问题根源
- 输入数据格式错误:创建DataFrame时,
01/04/2022会被Python当作除法运算,得到浮点数而非字符串日期,导致后续转datetime时出现异常。 - 逐行apply逻辑缺陷:原代码通过逐行生成日期序列再统计月份,不仅效率低,还可能因为索引不匹配导致join后新增列无法正常显示。
修正步骤
1. 修正输入数据
日期必须以字符串形式传入,避免被当作运算:
import pandas as pd df = pd.DataFrame( [["01/04/2022", "03/05/2022"], ["07/04/2022", "01/05/2022"]], columns=['Contract From', 'Contract To'] )
2. 简化预处理流程
统一处理日期格式,避免冗余操作:
df['Start Date'] = pd.to_datetime(df['Contract From'], dayfirst=True) df['End Date'] = pd.to_datetime(df['Contract To'], dayfirst=True).fillna(pd.to_datetime("31/03/2023", dayfirst=True))
3. 高效生成月份计数列
用更稳定的方式统计月份,并补全需要的月份列:
def get_month_counts(row): dates = pd.date_range(row['Start Date'], row['End Date'], freq='D') months = dates.to_period('M') return months.value_counts() # 生成每行的月份统计结果 month_counts = df.apply(get_month_counts, axis=1).fillna(0).astype(int) # 指定需要包含的月份范围,补全缺失月份为0 target_months = pd.period_range('2022-04', '2022-06', freq='M') month_counts = month_counts.reindex(target_months, axis=1, fill_value=0) # 将周期类型列名转为字符串,方便Excel识别 month_counts.columns = month_counts.columns.astype(str) # 合并原数据与统计结果 res = df[['Start Date', 'End Date']].join(month_counts) # 格式化日期列显示格式(可选,适配Excel阅读习惯) res['Start Date'] = res['Start Date'].dt.strftime('%d/%m/%Y') res['End Date'] = res['End Date'].dt.strftime('%d/%m/%Y')
4. 保存Excel文件
res.to_excel('month_counts_result.xlsx', index=False)
执行以上代码后,即可得到符合预期的结果,新增的月份列会正常显示在Excel文件中。
内容的提问来源于stack exchange,提问作者youguesswho
相关产品推荐
相关产品推荐

