Python 结合if条件和isnan语句

Python 结合if条件和isnan语句,python,python-2.7,pandas,if-statement,Python,Python 2.7,Pandas,If Statement,我尝试使用if语句并检查行值是否为NaN。事实证明,这比我想象的更难 以下是一个例子: df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'], 'data1': range(6), 'data2': ['A1', 'B1', 'NaN', 'A1', 'B1','NaN']}, columns = ['key', 'data

我尝试使用if语句并检查行值是否为NaN。事实证明,这比我想象的更难

以下是一个例子:

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'data1': range(6),
                   'data2': ['A1', 'B1', 'NaN', 'A1', 'B1','NaN']},
                   columns = ['key', 'data1', 'data2'])

def set_perf(row):
    if ("C" in row['key']) & (row['data2']=="NaN"):
        return row['data1']    
    else:        
        return 1

df['NewColumn'] = df.apply(set_perf, axis=1)  
输出是

  key  data1 data2  NewColumn
0   A      0    A1          1
1   B      1    B1          1
2   C      2   NaN          2
3   A      3    A1          1
4   B      4    B1          1
5   C      5   NaN          5
输出给出了我要查找的内容,这意味着我能够通过在if语句行['data2']==NaN中添加另一个条件来识别NaN值

我在我的原始数据集中应用了完全相同的逻辑,但它不起作用。这是一张快照

      NewPerfColumn sec_type tran_type LDI Bucket  Alpha vs Markit
0             1.000     GOVT        BB        NaN      3283.400526
1             1.000     GOVT        BB        NaN      6710.130364
2             1.000     GOVT        BB        NaN      3266.912122
3             1.000     GOVT        BB        NaN    113401.946471
4             1.000     GOVT        BB        NaN      1938.494818
5             1.000     GOVT        BB        NaN      9505.724498
6             1.000     GOVT        BB        NaN       192.196620
7             1.000  MUNITAX       RRP        NaN    -97968.750000
当我在if条件中添加行['LDI Bucket']==NaN时,无法识别值NaN。 以下是列LDI Bucket的不同值

data['LDI Bucket'].unique()
array([nan, u'0-3m', u'3-6m', u'6-9m', u'9m-1y'], dtype=object)
我错过什么了吗

我错过什么了吗

对。在MWE中,您将NaN表示为字符串。。。不是。它是一个浮点数,表示一个特定的数学量,它不等于任何其他量,包括它本身

NaN==NaN是真的,但NaN==NaN不是。这是您的问题的根本原因

这是一个简单的解决方案,使用pd.isnull测试NaNness

def set_perf(row):
    if ("C" in row['key']) and pd.isnull(row['data2']): 
        return row['data1']    
    else:        
        return 1
这里有一个更好的解决方案,使用np.where并将函数矢量化

df['NewColumn'] = np.where(
    df['key'].str.contains('C') & df['data2'].isnull(), df['data1'], 1
)

您可以使用numpy包或if语句,如

if pd.isnull(row[0]):
  print("do it more")   
isnull方法将处理您的Nan值。

如果是“Nan”

如果是np.NaN


&是一个按位and,用于操作,例如

In [5]: 1 & 3
Out[5]: 1
而这正是您所寻找的,因此if行应为:

  if ("C" in row['key']) and (row['data2']=="NaN"):

哎呀,你把NaN错当成NaN了,一个是浮点数,另一个是字符串。非常不同。除非您绝对确定没有直接的矢量化方法,否则不要使用apply。这里set_perf增加了不必要的复杂性;了解如何工作,例如,SO&beyond上的成百上千个示例。根据他们的代码,我假设他们希望检查str.contains,而不是==。不用担心,您可以使用str.contains。@cᴏʟᴅsᴘᴇᴇᴅ 不,我希望他们接受你的解释,因为你的解释中包含了更多关于这个问题的解释:-这个解决方案不完整。@coldspeed我在np.isnan之前尝试过方法一,但我在set_perf TypeError中得到了一个错误结果[I]=funcv文件,第2行:“没有为这种类型实现”,u“发生在索引37”。我试试第二种方法,然后再打给你。感谢you@SBad啊,可能是&vs和问题。是的,第二种方法会有效,而且会更好。@coldspeed方法2很好用。非常感谢。这里的钥匙在哪里。然而,npwhere可能不是嵌套if条件的最佳解决方案,这就是我倾向于使用df的原因。apply@SBad男人帮我一个忙,接受这个解释得很好的答案,而不是我可怜的answer@Wen对不起,伙计,我不是为了。。。如果你也得到了,我会非常高兴。只是想告诉OP他们只能接受一个答案
In [5]: 1 & 3
Out[5]: 1
  if ("C" in row['key']) and (row['data2']=="NaN"):