Pandas - 行是否低于具有相同id和列值的行

3

我是一名新手,正在学习Pandas。我有一个类似于下面的Pandas数据框:

df = pd.DataFrame(data={'id': [1, 1, 1, 2, 2, 2, 2], 'val1': [0, 1, 0, 0, 1, 0, 0]})

我想添加一列val2,用于指示某一行是否低于与其具有相同idval1 == 1的另一行。
结果将是一个数据框,如下所示:
df = pd.DataFrame(data={'id': [1, 1, 1, 2, 2, 2, 2], 'val1': [0, 1, 0, 0, 1, 0, 0], 'val2': [0, 0, 1, 0, 0, 1, 1]})

我的第一个想法是使用apply语句,但这些只逐行进行。从我的经验来看,for循环永远不是答案。任何帮助将不胜感激!


结果应该是 val1 -> val2 :) - Roelant
@Roelant,你这句话是什么意思?能详细解释一下吗? - Chris C
2个回答

5

让我们在groupby中尝试使用shiftcumsum

df['val2'] = df.groupby('id').val1.apply(
    lambda x: x.shift().cumsum()
).ge(1).astype(int)

或者,为了避免使用 lambda

df['val2'] = (    
   df.groupby('id')
     .val1.shift()
     .groupby(df.id)
     .cumsum()
     .ge(1)
     .astype(int)
)

df
   id  val1  val2
0   1     0     0
1   1     1     0
2   1     0     1
3   2     0     0
4   2     1     0
5   2     0     1
6   2     0     1

嘿,Coldspeed!这正是我正在寻找的,谢谢!你能帮我处理一个特殊情况吗(它和我的问题太相似了,所以我不想创建另一个问题)?如果我们要添加另一列,并且想要测试该行是否低于 val1 == 1 或另一列,比如 val3 == 1 的行,该怎么办? - Chris C
1
@ChrisC 类似这样:df['temp'] = df['val1'] + df['val3'] 然后 df['val_new'] = df.groupby('id').temp.apply( lambda x: x.shift().cumsum() ).ge(1).astype(int) - cs95

1
使用groupby+transform。类似于coldspeed的方法,但是使用bool转换来处理非零的cumsum值。
df['val2'] = df.groupby('id')['val1'].transform(lambda x: x.cumsum().shift())\
                                     .fillna(0).astype(bool).astype(int)

print(df)

   id  val1  val2
0   1     0     0
1   1     1     0
2   1     0     1
3   2     0     0
4   2     1     0
5   2     0     1
6   2     0     1

1
谢谢!我突然想到可能需要使用 group_by。 - Chris C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接