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

如何按时间顺序遍历DataFrame列并基于其他列生成输出列C?

解决Pandas DataFrame按指定逻辑生成计数列的问题

输入与期望输出

输入DataFrame

import pandas as pd

df = pd.DataFrame({
    'A': ['a', 'b', 'c', 'c', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'c', 'a', 'b', 'c'],
    'B': ['Good', 'Good', 'Good', 'Good', 'Good', 'Bad', 'Good', 'Good', 'Good', 'Good', 'Bad', 'Good', 'Good', 'Good', 'Good']
})

期望输出DataFrame

A     B  C
0  a  Good  1
1  b  Good  1
2  c  Good  1
3  c  Good  1
4  a  Good  1
5  b   Bad  1
6  c  Good  1
7  d  Good  1
8  a  Good  2
9  b  Good  2
10 c   Bad  2
11 c  Good  2
12 a  Good  3
13 b  Good  3
14 c  Good  3

核心逻辑

  • 初始计数n=1
  • 当B列值不为Good时:
    • 若A列是c或d,保持当前计数n,直到遇到A列非c/d的行时,再将n+1
    • 若A列不是c或d,直接将n+1,后续行使用新的计数
  • B列值为Good时,保持当前计数n不变

解决方案(高效向量化实现)

import pandas as pd

# 构造输入数据
df = pd.DataFrame({
    'A': ['a', 'b', 'c', 'c', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'c', 'a', 'b', 'c'],
    'B': ['Good', 'Good', 'Good', 'Good', 'Good', 'Bad', 'Good', 'Good', 'Good', 'Good', 'Bad', 'Good', 'Good', 'Good', 'Good']
})

# 1. 标记所有B≠Good的触发行
trigger = df['B'] != 'Good'
# 2. 标记所有A不是c/d的行
non_cd = ~df['A'].isin(['c', 'd'])

# 3. 处理延迟触发:标记需要延迟传递的触发点
pending_trigger = trigger & ~non_cd
# 累计延迟触发的数量,用于追踪待处理的计数需求
temp = pending_trigger.cumsum()

# 4. 生成有效触发点:
#    - 原本不需要延迟的触发(B≠Good且A非c/d)
#    - 延迟触发后遇到的第一个非c/d行(此时处理之前的计数需求)
valid_trigger = (temp.diff() != 0) & non_cd
valid_trigger |= trigger & non_cd

# 5. 计算最终计数列,初始值为1
df['C'] = valid_trigger.cumsum() + 1

# 查看结果
print(df)

代码解释

  1. 标记触发行:用trigger列记录所有B列不是Good的行,这些是潜在的计数触发点。
  2. 标记非c/d行:用non_cd列区分A列是否为c或d,用于判断是否需要延迟计数。
  3. 追踪延迟触发:pending_trigger标记需要延迟的触发点,temp累计这些点的数量,确保能追踪到待处理的计数需求。
  4. 生成有效触发点:
    • (temp.diff() != 0) & non_cd:当遇到非c/d行且累计延迟触发数有变化时,说明需要处理之前的延迟计数需求,标记为有效触发点。
    • trigger & non_cd:直接标记不需要延迟的触发点。
  5. 计算计数:对有效触发点做累计求和,再加1得到初始计数1,最终生成C列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:54:18