在Pandas中无需循环获取列前值?实现条件索引存储需求
在Pandas里不用循环就能实现你的需求
你要实现的是:新建一列c,当df['a']为True时存当前行的索引;如果df['a']是False,就存c列前一行的值。
先说说你这两次尝试的问题:
- Attempt 1:直接写
df['c'].shift(1)会报错,因为这时候df['c']还没创建呢,Pandas找不到这个列。 - Attempt 2:先把
c设成索引,再用np.where替换,但df['c'].shift(1)用的是原始索引列移位后的值,不是更新后的c列前一行的值。比如第2行a是False,它会取第1行的原始索引1,而不是我们要的第1行更新后的0,结果不对。
正确的实现方法
不用循环,用Pandas自带的函数就能搞定,给你几种简单的方式:
方法1:where + ffill组合
先只保留a为True时的索引,其他位置设成空值,再用向前填充把空值补上:
import pandas as pd import numpy as np df = pd.DataFrame({'a': [True, False, False, True, True, False], 'b': [0, 0, 0, 3, 4, 4]}) df['c'] = df.index.where(df['a']).ffill()
方法2:mask + ffill组合
和上面逻辑反过来,先把c设成索引,再把a为False的位置改成空值,然后向前填充:
df['c'] = df.index df['c'] = df['c'].mask(~df['a']).ffill()
方法3:cummax巧解(适合索引递增的情况)
因为你的索引是从0开始递增的,当a为True时用当前索引,否则取之前最大的索引,刚好符合需求:
df['c'] = (df.index * df['a']).cummax()
最终效果
不管用哪种方法,运行后df都会变成这样:
a b c 0 True 0 0.0 1 False 0 0.0 2 False 0 0.0 3 True 3 3.0 4 True 4 4.0 5 False 4 4.0
完全符合你的要求,而且全程没用到循环,处理大数据量的时候效率也更高。
内容的提问来源于stack exchange,提问作者aeiou
相关产品推荐
相关产品推荐

