如何在不同的列中使用多个条件来更新python中的新行值?

如何在不同的列中使用多个条件来更新python中的新行值?,python,python-3.x,pandas,dataframe,Python,Python 3.x,Pandas,Dataframe,这是当前的数据帧: id = ['793601486525702000','793601486525702000','793601710614802000','793601355214561000','793601355214561000','793601355214561000','793601355214561000','788130215436230000','788130215436230000','788130215436230000','788130215436230000'

这是当前的数据帧:

    id = ['793601486525702000','793601486525702000','793601710614802000','793601355214561000','793601355214561000','793601355214561000','793601355214561000','788130215436230000','788130215436230000','788130215436230000','788130215436230000','788130215436230000'] 
    time = ['11/1/2016 16:53','11/1/2016 16:53','11/1/2016 16:52','11/1/2016 16:55','11/1/2016 16:53','11/1/2016 16:53','11/1/2016 16:51','11/1/2016 3:09','11/1/2016 3:04','11/1/2016 2:36','11/1/2016 2:08','11/1/2016 0:28'] 
    rank = ['2','1','1','4','3','2','1','5','4','3','2','1'] 
    flag =['c_reply','c_start','u_start','u_reply','c_reply','c_reply','u_start','c_reply','c_reply','u_reply','u_reply','u_start']
    df = pd.DataFrame({"id": id, "time": time, "rank": rank, "flag": flag})

            id                time        rank     flag
                              .
                              .
    793601486525702000  11/1/2016 16:53    2      c_reply
    793601486525702000  11/1/2016 16:53    1      c_start
    793601710614802000  11/1/2016 16:52    1      u_start
    793601355214561000  11/1/2016 16:55    4      u_reply
    793601355214561000  11/1/2016 16:53    3      c_reply
    793601355214561000  11/1/2016 16:53    2      c_reply
    793601355214561000  11/1/2016 16:51    1      u_start
    788130215436230000  11/1/2016 3:09     5      c_reply
    788130215436230000  11/1/2016 3:04     4      c_reply
    788130215436230000  11/1/2016 2:36     3      u_reply
    788130215436230000  11/1/2016 2:08     2      u_reply
    788130215436230000  11/1/2016 0:28     1      u_start
                              .
                              .
我的数据集有数千行。
列“id”:一个id可能有多行/记录。行具有相同的id表示它们在同一组中。
“rank”列按同一组id的时间顺序排列

我想使用循环或函数创建两个新列“reply”和“reply_time”,这两个列基于我的数据帧中的多个列:“id”、“rank”、“time”和“flag”。
步骤1:选择同一id组中的行(按id列分组)
步骤2:更新“回复”列值:我想设置的条件如下:

值“0”:秩为“1”,标志为“u\u开始”,标志列中没有“c\u回复”
值“1”:秩为“1”,标志为“u\u开始”,标志列中有“c\u回复”
值“2”:标志列中第一个/最早的c_应答。(如果有多个c_回复,请列出最早的c_回复(排名列中较小的值))
值“3”:如果不满足上述条件,则应将行分配到此类别,包括(1)秩='1'和标志='c_-start'或(2)秩>='2'和标志='u-reply'或(3)秩>='2'和标志='c_-reply',而不是标志列中的第一个c_-reply或(4)秩>='2'和标志='c_-reply'和标志列中的无'u-start'

步骤3:更新“回复时间”列值:我想设置的条件如下:
值“时间”:秩为“1”,标志为“u_开始”,且标志列中有“c_回复”,列出第一个/最早的“c_回复”时间。
值“na”:如果不满足上述条件,则应将行分配给“na”

目标输出如下所示:

            id                 time       rank      flag   reply   reply_time
    793601486525702000  11/1/2016 16:53     2     c_reply    3      na
    793601486525702000  11/1/2016 16:53     1     c_start    3      na
    793601710614802000  11/1/2016 16:52     1     u_start    0      na
    793601355214561000  11/1/2016 16:55     4     u_reply    3      na
    793601355214561000  11/1/2016 16:53     3     c_reply    3      na
    793601355214561000  11/1/2016 16:53     2     c_reply    2      na
    793601355214561000  11/1/2016 16:51     1     u_start    1      11/1/2016 16:53
    788130215436230000  11/1/2016 3:09      5     c_reply    3      na
    788130215436230000  11/1/2016 3:04      4     c_reply    2      na
    788130215436230000  11/1/2016 2:36      3     u_reply    3      na
    788130215436230000  11/1/2016 2:08      2     u_reply    3      na
    788130215436230000  11/1/2016 0:28      1     u_start    1      11/1/2016 3:04
这似乎是一个简单的问题,但我在任何地方都找不到。
我现在使用excel进行手动编码,但我认为应该有一种更快的方法通过使用python来解决这个问题。

非常感谢您的帮助。非常感谢

花费的时间比预期的要长一点。我没有足够的时间回答你的第二个问题(不管怎样,你在问SO时应该只问一个问题),所以我将帮助你直到第2步:

import pandas as pd
import numpy as np

id = ['793601486525702000','793601486525702000','793601710614802000','793601355214561000','793601355214561000','793601355214561000','793601355214561000','788130215436230000','788130215436230000','788130215436230000','788130215436230000','788130215436230000'] 
time = ['11/1/2016 16:53','11/1/2016 16:53','11/1/2016 16:52','11/1/2016 16:55','11/1/2016 16:53','11/1/2016 16:53','11/1/2016 16:51','11/1/2016 3:09','11/1/2016 3:04','11/1/2016 2:36','11/1/2016 2:08','11/1/2016 0:28'] 
rank = ['2','1','1','4','3','2','1','5','4','3','2','1'] 
flag =['c_reply','c_start','u_start','u_reply','c_reply','c_reply','u_start','c_reply','c_reply','u_reply','u_reply','u_start']
df = pd.DataFrame({"id": id, "time": time, "rank": rank, "flag": flag})
让我们从最困难的条件开始:

ids_c3 = pd.DataFrame(df[df.flag=='c_reply'].groupby('id')['rank'].min())
ids_c3['reply'] = 2
df= df.merge(ids_c3, on=['id','rank'], how='left')
首先,我们找到了具有
c_reply
的id,并获得了这些id的最小
等级。然后转换为数据帧,并用2标记。然后,我将其与原始数据帧合并以创建
reply
列。现在我们缺少数字0、1和3

对于数字1和0:

df['is_c_reply'] = df.groupby('id').flag.transform(lambda x: x.eq('c_reply').any())
c1= (df['rank']=='1') & (df.flag=='u_start') & (df.is_c_reply==0)
c2= (df['rank']=='1') & (df.flag=='u_start') & (df.is_c_reply==1)
df['reply'] = np.select([c1,c2],[0,1], default=df.reply)
我们编写了您指定的条件:
c1
用于
0
c2
用于
1
。然后使用
np.select()
填充回复列

现在我们只缺少
3
。如上所述,其他所有内容都是3,所以您只需
fillna()

我们完了


可能有更快的方法可以做到这一点,尽管
np似乎是可行的。select()
groupby()
,如果我有时间的话,我会尝试一会儿回复
df.reply = df.reply.fillna(3)