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

如何基于Pandas DataFrame某列值创建倒计数新列

问题描述

我需要在Pandas DataFrame中基于is_longest_activation列创建新列is_in_longest_activation,规则如下:

  • 当is_longest_activation列出现非零值N时,从该行开始向上倒计数至0,覆盖N行(包含当前行)
  • 若计数范围出现重叠(前一个计数还未到0时又出现新的非零值),则以新的非零值为起点重新计数

示例数据

quarter_houris_longest_activationis_in_longest_activation
100
200
301
422
505
606
707
808
909
101010
1100

当前尝试的代码

UpEnergy["is_longest_activation"] = UpEnergy["consecutive_activations_count"].where(
    UpEnergy["consecutive_activations_count"] == UpEnergy["consecutive_activations_count_daily_max"],
    0
)

counter = UpEnergy["is_longest_activation"].where(UpEnergy["is_longest_activation"].ne(0)).bfill().fillna(0, downcast='infer')
UpEnergy["is_in_longest_activation"] = counter.sub(
    UpEnergy.groupby(counter).cumcount(ascending=False)
).clip(lower=0)
解决方案

现有代码的bfill()逻辑无法处理计数重叠的情况,下面提供两种可行实现:

方法1:反向遍历(直观易理解)

通过从DataFrame末尾向前遍历,天然优先处理靠后的非零值,解决重叠覆盖问题:

# 初始化目标列
UpEnergy["is_in_longest_activation"] = 0
current_count = 0

# 从最后一行向前遍历
for i in reversed(range(len(UpEnergy))):
    # 遇到非零值时重置计数
    if UpEnergy.loc[i, "is_longest_activation"] != 0:
        current_count = UpEnergy.loc[i, "is_longest_activation"]
    # 赋值当前计数并递减
    UpEnergy.loc[i, "is_in_longest_activation"] = current_count
    if current_count > 0:
        current_count -= 1

方法2:向量化优化(适合大数据集)

通过计算非零值的覆盖区间,去重后生成计数序列,效率更高:

# 提取所有非零值的位置和对应数值
non_zero_records = UpEnergy[UpEnergy["is_longest_activation"] != 0].reset_index()
non_zero_records["start_idx"] = non_zero_records["index"] - non_zero_records["is_longest_activation"] + 1
non_zero_records["end_idx"] = non_zero_records["index"]

# 从后往前排序,保留每个位置最新的覆盖区间(解决重叠)
non_zero_records = non_zero_records.sort_values("index", ascending=False).drop_duplicates(subset=pd.RangeIndex(len(UpEnergy)), keep="first")

# 生成目标列结果
result = pd.Series(0, index=UpEnergy.index)
for _, row in non_zero_records.iterrows():
    start_pos = max(0, row["start_idx"])
    end_pos = row["end_idx"]
    # 生成从N到0的倒计数序列
    result.loc[start_pos:end_pos] = range(row["is_longest_activation"], -1, -1)

UpEnergy["is_in_longest_activation"] = result

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:42:41