You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas实现:计算DataFrame中到下一个1的间隔月份数

解决方法:计算到下一个1的月份间隔

你可以用两种方法实现这个需求,一种是直观的位置查找法,另一种是适合大数据集的高效分组法,下面分别说明:

方法一:位置查找的直观实现

这种方法直接定位所有值为1的行的位置,再计算每一行到下一个1的位置差(因为你的索引是连续月度数据,位置差正好等于月份数):

import pandas as pd
import numpy as np

# 你的示例数据
Y = [0,0,1,1,0,0,0,0,1,1,1]
X = pd.date_range(start = "2010", freq = "MS", periods = len(Y))
df = pd.DataFrame({'R': Y}, index = X)

# 获取所有R=1的行的位置索引
one_positions = np.where(df['R'] == 1)[0]

# 定义函数:计算当前行到下一个1的月份数
def next_one_distance(row_idx):
    # 筛选当前行之后的所有1的位置
    future_ones = one_positions[one_positions > row_idx]
    if len(future_ones) > 0:
        # 返回最近的1与当前行的位置差
        return future_ones[0] - row_idx
    else:
        # 若没有后续的1(比如末尾全是0),可根据需求返回0或其他值
        return 0

# 给每一行计算F值
df['F'] = [next_one_distance(i) for i in range(len(df))]

运行后就能得到你期望的结果:

R  F
2010-01-01  0  2
2010-02-01  0  1
2010-03-01  1  0
2010-04-01  1  0
2010-05-01  0  4
2010-06-01  0  3
2010-07-01  0  2
2010-08-01  0  1
2010-09-01  1  0
2010-10-01  1  0
2010-11-01  1  0

方法二:分组反向累计计数(高效版)

如果你的数据量很大,上面的循环方法效率会受限,推荐用这种基于pandas分组的方案——核心逻辑是反转数据后,对每个以1开头的组做累计计数,再反转回原顺序:

import pandas as pd

# 你的跨年度示例数据
Y = [0,0,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,1,1,1]
X = pd.date_range(start = "2010", freq = "MS", periods = len(Y))
df = pd.DataFrame({'R': Y}, index = X)

# 反转数据框
df_reversed = df.iloc[::-1].copy()

# 创建分组:每次遇到R=1就开启新分组(反转后,原数据的"下一个1"变成了分组的起始)
df_reversed['group'] = df_reversed['R'].cumsum()

# 每个分组内累计计数,这个数值就是原数据中到下一个1的月份数
df_reversed['F'] = df_reversed.groupby('group').cumcount()

# 将结果反转回原顺序,赋值给原数据框
df['F'] = df_reversed['F'].iloc[::-1]

这个方法完全利用pandas内置函数,避免了显式循环,处理大数据集时速度更快,也能完美适配跨年度的复杂场景。

为什么你的原代码只处理了第一部分?

你的原代码仅手动处理了从第一个索引到第一个1的区间,没有循环覆盖后续所有需要计算的区间。上面的两种方法都自动遍历了所有行,所以能得到完整的结果。

内容的提问来源于stack exchange,提问作者measure_theory

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:00:02