Pandas按ID分组对比上一行值修改level列单元格值方法
问题根因
你之前用shift()实现时,对比的是原始数据中未更新的上一行level值,修改操作不会向后传递,因此只能修改紧邻更小值的第一行,后续行无法同步更新。
你的需求本质是:按ID分组后,保留截至当前行出现过的最小level值,也就是对level列做分组累积最小值计算,不需要手动逐行遍历。
最简实现(data.table)
直接调用内置累积最小值函数cummin()即可,代码运行结果和你给出的预期输出完全一致:
library(data.table) setDT(df) # 按ID分组计算level的累积最小值 df[, level := cummin(level), by = ID]
结果验证
运行后输出如下,完全匹配需求:
ID year level 1: 1 2000 NA 2: 1 2001 3 3: 1 2002 3 4: 1 2003 2 5: 1 2004 1 6: 2 2000 1 7: 2 2001 1 8: 2 2002 1 9: 2 2003 1 10: 2 2004 1
补充说明
cummin()会自动迭代传递计算结果:每一行的取值都是从分组第一行到当前行的最小值,刚好符合“如果上一行(更新后)值更小就替换”的逻辑,同时会自动保留分组首行的NA值,不需要额外处理缺失值。- 如果你后续有更复杂的迭代规则,无法直接用累积函数实现,可以用
Reduce()完成迭代计算,本需求对应的写法如下,运行结果和cummin()完全一致:
df[, level := Reduce(min, level, accumulate = TRUE), by = ID]
- 不推荐写逐行for循环实现,数据量较大时运行效率会远低于内置的向量化函数。
内容的提问来源于stack exchange,提问作者ari6739
相关产品推荐
相关产品推荐

