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

问题描述 投票:2回答:1

我有两个dfs,ABA就像,

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中相应的行(AB上连接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

我想知道是否有更好的方法来做到这一点,在更简洁和有效的代码方面。

python-3.x pandas dataframe
1个回答
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。

© www.soinside.com 2019 - 2024. All rights reserved.