如何按days_div规则将Dataframe月度BP/RE数据转为日度数据?
解决方案:月度Dataframe转日度粒度并按规则拆分数值
核心思路
- 将年份+月份转换为当月起始日期,利用Pandas自动生成当月完整日度日期序列(自动适配闰年2月)
- 将每行月度数据拆分为当月每一天的行记录
- 根据
days_div判断日期区间,计算对应日度BP/RE值,超出区间的设为0
完整代码实现
import pandas as pd import numpy as np # 示例输入Dataframe(替换为你的实际数据) data = { 'Year': [2023, 2023, 2023], 'Month': ['January', 'January', 'February'], 'Region': ['Kerala', 'Kerala', 'Delhi'], 'Factory': ['A', 'A', 'A'], 'Category': ['QA', 'QA', 'QS'], 'Parameter': ['efficiency', 'Tur FS', 'UFS'], 'UOM': ['%', 'MT', 'T'], 'BP': [25, 23, 27], 'RE': [28, 26, 26], 'days_div': [25, 29, 27] } df = pd.DataFrame(data) # 1. 生成当月起始日期,并创建当月完整日度日期序列 df['month_start'] = pd.to_datetime(df['Year'].astype(str) + ' ' + df['Month']) df['daily_dates'] = df.apply( lambda row: pd.date_range( start=row['month_start'], end=row['month_start'] + pd.offsets.MonthEnd(0), freq='D' ), axis=1 ) # 2. 将月度数据拆分为日度行 df = df.explode('daily_dates').reset_index(drop=True) # 3. 计算日度BP和RE值 df['day_of_month'] = df['daily_dates'].dt.day daily_bp = df['BP'] / df['days_div'] daily_re = df['RE'] / df['days_div'] df['BP'] = np.where(df['day_of_month'] <= df['days_div'], daily_bp, 0) df['RE'] = np.where(df['day_of_month'] <= df['days_div'], daily_re, 0) # 4. 整理输出列(保留需要的字段,移除中间临时列) output_df = df.drop(columns=['month_start', 'day_of_month']).rename(columns={'daily_dates': 'Date'}) # 查看结果示例 print(output_df.head())
关键细节说明
- 闰年适配:
pd.date_range结合MonthEnd会自动根据年份判断当月天数,比如2020年2月会生成29条日期记录 - 除以0防护:如果你的数据中存在
days_div=0的情况,建议提前过滤:df = df[df['days_div'] > 0] - 精度控制:如果需要保留小数位数,可以用
df['BP'] = df['BP'].round(2)调整
输出示例(截取部分)
Year Month Region Factory Category Parameter UOM BP RE days_div Date 0 2023 January Kerala A QA efficiency % 1.000000 1.120000 25 2023-01-01 1 2023 January Kerala A QA efficiency % 1.000000 1.120000 25 2023-01-02 ... 25 2023 January Kerala A QA efficiency % 0.000000 0.000000 25 2023-01-26 26 2023 January Kerala A QA efficiency % 0.000000 0.000000 25 2023-01-27
内容的提问来源于stack exchange,提问作者AbinBenny
相关产品推荐
相关产品推荐

