基于np.where实现多数据集月度列循环填充的技术求助
月度数据填充计算问题
数据集定义
数据集1 df_A1
import pandas as pd df_A1 = pd.DataFrame([[46, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[47, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], columns=['RTMB','RTMM',1,2,3,4,5,6,7,8,9,10])
初始表格:
| RTMB | RTMM | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 46 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 47 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
数据集2 df_Pokok
import pandas as pd df_Pokok = pd.DataFrame([[6852110,9228999,10497987,11941460,0,0],[34794991,18556525,21108047,24010403,0,0]], columns=[0,1,2,3,4,5])
初始表格:
| 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| 6852110 | 9228999 | 10497987 | 11941460 | 0 | 0 |
| 34794991 | 18556525 | 21108047 | 24010403 | 0 | 0 |
需求说明
- df_Pokok的列0-5为年度单位,当月度列序号不满足
col <= df_A1['RTMM']时,需将对应年度列值除以12后填入df_A1的月度列; - df_A1的
RTMB(总月度数)、RTMM(初始月度数)为月度单位; - 仅当df_A1的月度列序号小于等于
RTMM时,直接使用df_Pokok的列0值; - 持续填充月度列直到列序号不超过
RTMB,超出的月份填0。
当前代码问题
尝试用多层np.where实现,但无法完成RTMM之后的年度值循环重复填充逻辑:
for col in df_A1.iloc[:, 5:]: df_A1[col] = np.where(int(col) > df_VD['RTM_B'], 0, np.where(int(col) <= (df_VD['RTMM']), df_VD['POKVER'], np.where(((((df_VD['RTM_B']).astype(int) - (int(col)-1))%12) == 0) ,0 ,0)))
期望结果
| RTMB | RTMM | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 46 | 4 | 685,2110 | 685,2110 | 685,2110 | 685,2110 | 769,083 | 769,083 | 769,083 | 769,083 | 769,083 | 769,083 |
| 47 | 2 | 34,794,991 | 34,794,991 | 1,546,377 | 1,546,377 | 1,546,377 | 1,546,377 | 1,546,377 | 1,546,377 | 1,546,377 | 1,546,377 |
注:769,083由df_Pokok列1的值(9,228,999)除以12取整得到,需连续填充12个月,之后切换为df_Pokok列3的值除以12,继续填充至RTMB对应的月份。
解决方案
核心思路
- 逐行处理:针对每行的
RTMB、RTMM参数和对应的df_Pokok年度值独立计算; - 分阶段填充:
- 月度序号>RTMB:填0;
- 月度序号<=RTMM:直接取df_Pokok列0的值;
- 月度序号>RTMM:计算该月份属于RTMM之后的第几个年度周期,对应取df_Pokok的列值并除以12取整;
- 边界兜底:处理超出df_Pokok列数的情况,避免索引越界。
实现代码
import pandas as pd import numpy as np # 初始化数据集 df_A1 = pd.DataFrame([[46, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[47, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], columns=['RTMB','RTMM',1,2,3,4,5,6,7,8,9,10]) df_Pokok = pd.DataFrame([[6852110,9228999,10497987,11941460,0,0],[34794991,18556525,21108047,24010403,0,0]], columns=[0,1,2,3,4,5]) # 提取所有月度列并转为整数类型 month_columns = df_A1.columns[2:].astype(int) # 逐行处理填充逻辑 for row_idx in df_A1.index: max_month = df_A1.loc[row_idx, 'RTMB'] initial_month = df_A1.loc[row_idx, 'RTMM'] annual_values = df_Pokok.loc[row_idx].values for month in month_columns: if month > max_month: # 超过总月度数的月份填0 df_A1.loc[row_idx, month] = 0 elif month <= initial_month: # 初始月度范围内直接用年度列0的值 df_A1.loc[row_idx, month] = annual_values[0] else: # 计算当前月份属于RTMM之后的第几个年度周期(从1开始) cycle_index = (month - initial_month - 1) // 12 + 1 # 确保不超出df_Pokok的列范围 if cycle_index >= len(annual_values): df_A1.loc[row_idx, month] = 0 else: # 年度值除以12取整 df_A1.loc[row_idx, month] = int(annual_values[cycle_index] / 12) # 可选:格式化输出为带千分位的格式 pd.options.display.float_format = '{:,.0f}'.format print(df_A1)
代码说明
- 年度周期计算:
(month - initial_month - 1) // 12 + 1精准定位RTMM之后的月份对应的年度数据列,比如第5个月(initial_month=4):(5-4-1)//12 +1 = 0+1=1,对应df_Pokok的列1,与期望结果完全匹配; - 边界处理:对超出RTMB和df_Pokok列数的情况都做了兜底,避免运行报错;
- 行级独立计算:保证每行的参数逻辑独立生效,符合数据集的业务规则。
内容的提问来源于stack exchange,提问作者Edo
相关产品推荐
相关产品推荐

