2017-02-27 58 views
1

鉴于以下虚拟数据,我的目标是确定员工是否在2014年底就业,并返回一个新的布尔列来达到此目的。熊猫:条件声明不能按预期工作

name hire_date termination_date grade_2014 
James 1999-01-01 NaT    10.0 
Amara 2015-12-07 NaT    NaN 
Haj  2012-08-13 2016-04-04   9.0 
Bill 1999-01-12 2014-02-04   7.0 

我写了下面的列表comp来实现这一点。

from itertools import izip 
df['active_end_2014'] = ['true' if 
        (hire < pd.Timestamp(2014, 12, 31) and termination == pd.NaT) | 
        (termination > pd.Timestamp(2015, 1, 1) and grade_2014 != np.nan) 
        else 'false' for grade_2014, termination, hire in izip(df['grade_2014'], 
                      df['termination_date'], 
                      df['hire_date'])] 

正确的布尔值是为所有员工返回的,但James会得到'false'。

df[df['name'] == 'James']

name hire_date termination_date grade_2014 active_end_2014 
James 1999-01-01 NaT     10.0  false 

他为什么不分配 '真',毫无疑问他满足这个条件:

hire < pd.Timestamp(2014, 12, 31) and termination == pd.NaT

这是用括号问题或pd.Nat选择?或者,也许我如何更广泛地构建列表comp?

+0

我不知道'pd.NaT',但也许它就像'NaN','NaN == NaN'返回False。 – polku

回答

2

你应该正确使用boolean indexing

In [81]: df['active_end_2014'] = \ 
    ...:  ((df.hire_date < '2014-12-31') & df.termination_date.isnull()) | \ 
    ...:  ((df.termination_date > '2015-01-01') & df.grade_2014.notnull()) 

In [82]: df 
Out[82]: 
    name hire_date termination_date grade_2014 active_end_2014 
0 James 1999-01-01    NaT  10.0   True 
1 Amara 2015-12-07    NaT   NaN   False 
2 Haj 2012-08-13  2016-04-04   9.0   True 
3 Bill 1999-01-12  2014-02-04   7.0   False 
1

您比较NaN的与==,这将导致错误。使用pd.isnull

>>> pd.NaT == pd.NaT 
False 
>>> pd.isnull(pd.NaT) 
True