如何根据条件的结果向pandas DataFrame添加列

2024-10-02 02:39:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在DataFrame中添加一列,根据此人是否在激励之前或之后被阻止。在

例如,在row 0中,此人在IncentiveStart日期之后Blocked,因此1会出现在那里,这样在结束时我可以计算每一次。同样,如果一个人在激励之后Cleared,那么1将进入相应的单元格。在

我想不出用Pandas做这个,因为我能想到的唯一方法是使用if语句。如果有帮助,columns = ReceiptDate, IncentiveStartDateTime对象。在

提前谢谢。在

这是我的DataFrame,下面是我想要的样子:

    df = pd.DataFrame([['AMW','Blocked','5/22/2011','10/1/2015','TRUE'], 
                            ['AMW','Cleared','6/1/2011','','FALSE'],
                            ['CRC','Cleared','6/1/2011','','FALSE'],
                            ['BRO','Blocked','6/2/2016','10/1/2015','TRUE'],
                            ['WOR','Cleared','5/12/2011','','FALSE'],
                            ['BUR','Cleared','6/9/2015','10/1/2014','FALSE'],
                            ['COM','Cleared','6/1/2011','','FALSE'],], 
                           columns=['person','Clear_Decline','ReceiptDate',
                                    'IncentiveStart','hasIncentive'])

      person Clear_Decline ReceiptDate IncentiveStart hasIncentive
    0    AMW       Blocked   5/22/2011      10/1/2015         TRUE
    1    AMW       Cleared    6/1/2011                       FALSE
    2    CRC       Cleared    6/1/2011                       FALSE
    3    BRO       Blocked    6/2/2016      10/1/2015         TRUE
    4    WOR       Cleared   5/12/2011                       FALSE
    5    BUR       Cleared    6/9/2015      10/1/2014        FALSE
    6    COM       Cleared    6/1/2011                       FALSE

    df = pd.DataFrame([['AMW','Blocked','5/22/2011','10/1/2015','TRUE',0,0,1,0], 
                            ['AMW','Cleared','6/1/2011','','FALSE',1,0,0,0],
                            ['CRC','Cleared','6/1/2011','','FALSE',1,0,0,0],
                            ['BRO','Blocked','6/2/2016','10/1/2015','TRUE',0,0,0,1],
                            ['WOR','Cleared','5/12/2011','','FALSE',1,0,0,0],
                            ['BUR','Cleared','6/9/2015','10/1/2014','FALSE',0,1,0,0],
                            ['COM','Cleared','6/1/2011','','FALSE',1,0,0,0],], 
                           columns=['person','Clear_Decline','ReceiptDate',
                                    'IncentiveStart','hasIncentive',
                                    'Clearedbefore','ClearedAfter','Blockedbefore','BlockedAfter'])

person Clear_Decline ReceiptDate IncentiveStart hasIncentive  Clearedbefore  ClearedAfter  Blockedbefore  BlockedAfter
    0    AMW       Blocked   5/22/2011      10/1/2015         TRUE              0             0              1             0
    1    AMW       Cleared    6/1/2011                       FALSE              1             0              0             0
    2    CRC       Cleared    6/1/2011                       FALSE              1             0              0             0
    3    BRO       Blocked    6/2/2016      10/1/2015         TRUE              0             0              0             1
    4    WOR       Cleared   5/12/2011                       FALSE              1             0              0             0
    5    BUR       Cleared    6/9/2015      10/1/2014        FALSE              0             1              0             0
    6    COM       Cleared    6/1/2011                       FALSE              1             0              0             0

Tags: comfalsetruedataframepersoncrcbroclear
3条回答

另一种方法是将if语句定义为函数,然后沿轴应用它们。例如:

# Taking `df` defined in OP's question
df.ReceiptDate =  pd.to_datetime(df.ReceiptDate)
df.IncentiveStart = pd.to_datetime(df.IncentiveStart)

df.ReceiptDate =  pd.to_datetime(df.ReceiptDate)
df.IncentiveStart = pd.to_datetime(df.IncentiveStart)

def condition(row):
    if row['Clear_Decline'] == 'Cleared':
        if row['hasIncentive'] == 'FALSE':
            if row['ReceiptDate']>row['IncentiveStart']:
                return 0
            else:
                return 1
        else:
            return 1
    else:
        return 0

df['Clearedbefore'] = df.apply(condition, axis=1)

这样,您的代码会更长,但逻辑可能会更清晰。在

我展示了df['BlockedAfter']的解决方案,我希望您可以对所有变量重复此方法

第一个-转换为日期时间

df['ReceiptDate'] = pd.to_datetime(df['ReceiptDate'])
df['IncentiveStart'] = pd.to_datetime(df['IncentiveStart'])

然后我们得到时差

^{pr2}$

和一个新列,有两个条件

df['BlockedAfter'] = 0
df.ix[(df['time'] > 0) & (df['Clear_Decline'] == 'Blocked'), 'BlockedAfter'] = 1
df['BlockedAfter']
0    1
1    0
2    0
3    0
4    0
5    0
6    0
Name: BlockedAfter, dtype: int64

感谢@Edward为我指明了正确的方向。在

我不认为日期需要转换,因为它们已经是正确的类型,这样熊猫就可以检查哪一个更老了。在

我想到了爱德华的回答:

df['BlockedAfter'] = 0
df.ix[(df['Clear_Decline'] == 'Blocked') & (df['ReceiptDate'] >= df['IncentiveStart']) & 
                    (df['IncentiveStart']).notnull(), 'BlockedAfter'] = 1

  person Clear_Decline ReceiptDate IncentiveStart hasIncentive  BlockedAfter
0    AMW       Blocked  2011-05-22     2015-10-01         TRUE             0
1    AMW       Cleared  2011-06-01            NaT        FALSE             0
2    CRC       Cleared  2011-06-01            NaT        FALSE             0
3    BRO       Blocked  2016-06-02     2015-10-01         TRUE             1
4    WOR       Cleared  2011-05-12            NaT        FALSE             0
5    BUR       Cleared  2015-06-09     2014-10-01        FALSE             0
6    COM       Cleared  2011-06-01            NaT        FALSE             0

相关问题 更多 >

    热门问题