pandas根据另一个df的列上的一个条件为df创建一个布尔列

时间:2017-12-19 10:33:59

标签: python-3.x pandas dataframe

我有两个dfABA就像,

date        id
2017-10-31  1
2017-11-01  2
2017-08-01  3

B就像,

type    id 
1       1
2       2
3       3

我想为has_b创建一个新的布尔列A,如果其对应的行(True加入A,则将列值设置为B id中的B}没有type == 1,其时间差值为>与datetime.utcnow().day相比90天;和False否则,这是我的解决方案

    B = B[B['type'] != 1]

    A['has_b'] = A.merge(B[['id', 'type']], how='left', on='id')['date'].apply(lambda x: datetime.utcnow().day - x.day > 90)

    A['has_b'].fillna(value=False, inplace=True)

希望看到A结果,

date        id    has_b    
2017-10-31  1     False
2017-11-01  2     False
2017-08-01  3     True

我想知道是否有更好的方法可以做到这一点,就更简洁高效的代码而言。

1 个答案:

答案 0 :(得分:1)

首先在A -

上合并Bid
i = A.merge(B, on='id')

现在,计算has_b -

x = i.type.ne(1)
y = (pd.to_datetime('today') - i.date).dt.days.gt(90)
i['has_b'] = (x & y)

合并iA -

C = A.merge(i[['id', 'has_b']], on='id')
C

        date  id  has_b
0 2017-10-31   1  False
1 2017-11-01   2  False
2 2017-08-01   3   True

<强>详情

x将为第一个条件返回一个布尔掩码。

i.type.ne(1)

0    False
1     True
2     True
Name: type, dtype: bool

y将为第二个条件返回一个布尔掩码。使用to_datetime('today')获取当前日期,从日期列中减去此日期,然后使用dt.days访问days组件。

(pd.to_datetime('today') - i.date).dt.days.gt(90)

0    False
1    False
2     True
Name: date, dtype: bool

如果AB的ID不对齐,您可能需要合并而不是内部合并,最后一步 -

C = A.merge(i[['id', 'has_b']], on='id', how='left')
在这种情况下,

C的has_b列将包含NaN。