基于年份值递归填充DataFrame中缺失的年份列
问题描述
现有如下格式的DataFrame:
Month Year Value1 Value2 ... Jul 1.1 2.2 Aug 1.1 2.3 Sep 1.1 2.6 Oct 1.1 2.2 Nov 1.1 2.2 Dec 1.1 2.2 Jan 1.1 2.2 Feb 1.1 2.2 Mar 1.1 2.2 Apr 1.1 2.2 May 1.1 2.2 Jun 1.1 2.2 Jul 1.1 2.2 Aug 1.1 2.2 Sep 1.1 2.2 Oct 1.1 2.2 Nov 1.1 2.2 Dec 1.1 2.2 Jan 1.1 2.2 Feb 1.1 2.2 Mar 1.1 2.2 Apr 1.1 2.2 May 1.1 2.2 Jun 1.1 2.2 Jul 2022 1.1 2.2
目标是填充Year列,最后一行已固定为当前年份(示例中是2022),已通过以下代码完成当前年份从对应月份到1月的行填充:
month_val1 = df['Month'].values[-1] # 获取最后一行的月份 year_val1 = df['Year'].values[-1] # 获取最后一行的年份 month_count = month_dict[month_val1] # 获取需要填充当前年份的行数(比如Jul对应7行) df['Year'].iloc[-month_count:] = year_val1 # 填充当前年份的对应行
需要实现反向递归填充从倒数第month_count+1行到第一行的Year列,且DataFrame行数不固定,不能仅按12行递减填充。预期结果如下:
Month Year Value1 Value2 ... Jul 2020 1.1 2.2 Aug 2020 1.1 2.3 Sep 2020 1.1 2.6 Oct 2020 1.1 2.2 Nov 2020 1.1 2.2 Dec 2020 1.1 2.2 Jan 2021 1.1 2.2 Feb 2021 1.1 2.2 Mar 2021 1.1 2.2 Apr 2021 1.1 2.2 May 2021 1.1 2.2 Jun 2021 1.1 2.2 Jul 2021 1.1 2.2 Aug 2021 1.1 2.2 Sep 2021 1.1 2.2 Oct 2021 1.1 2.2 Nov 2021 1.1 2.2 Dec 2021 1.1 2.2 Jan 2022 1.1 2.2 Feb 2022 1.1 2.2 Mar 2022 1.1 2.2 Apr 2022 1.1 2.2 May 2022 1.1 2.2 Jun 2022 1.1 2.2 Jul 2022 1.1 2.2
解决方案
核心思路是从已填充的年份区域向前推导,每次确定上一个年份的覆盖范围,逐步填充到第一行。具体实现如下:
- 首先确保存在月份到数字的映射字典(基础依赖):
month_dict = {'Jan':1, 'Feb':2, 'Mar':3, 'Apr':4, 'May':5, 'Jun':6, 'Jul':7, 'Aug':8, 'Sep':9, 'Oct':10, 'Nov':11, 'Dec':12}
- 执行你已有的当前年份填充代码后,添加反向填充逻辑:
# 你已有的填充当前年份的代码 month_val1 = df['Month'].values[-1] year_val1 = df['Year'].values[-1] month_count = month_dict[month_val1] df['Year'].iloc[-month_count:] = year_val1 # 反向填充剩余行 current_pos = len(df) - month_count - 1 current_year = year_val1 - 1 while current_pos >= 0: # 获取当前起始位置的月份 current_month = df['Month'].iloc[current_pos] # 计算当前月份到当年12月的行数 rows_needed = 12 - month_dict[current_month] + 1 # 确定实际填充的行数:避免越界,取剩余行数和需要行数的最小值 fill_rows = min(rows_needed, current_pos + 1) # 填充对应行的年份 df['Year'].iloc[current_pos - fill_rows + 1 : current_pos + 1] = current_year # 更新位置和年份,继续循环 current_pos -= fill_rows current_year -= 1
代码说明
- 循环从已填充区域的前一行开始,每次处理一个完整的年份段(从当前月份到12月),如果剩余行数不足一个完整段,则填充到第一行
- 用
min(rows_needed, current_pos + 1)确保不会越界,完美适配行数不固定的场景 - 年份每次循环自动减1,实现反向递归的年份递减逻辑
内容的提问来源于stack exchange,提问作者RSM
相关产品推荐
相关产品推荐

