首页 > 解决方案 > 使用跨多列的列表理解将所有非 NaN 值转换为 1

问题描述

这里有一些数据:

test = pd.DataFrame([[np.nan,"cat","mouse", 'tiger'],
    ["tiger","dog","elephant", "mouse"],
    ["cat",np.nan,"giraffe", "cat"],
    [np.nan,np.nan,"ant", "ant"]],  columns=["animal1","animal2","animal3", "animal4"])

我想将所有 NaN 转换为 0,并将所有响应转换为 1。

#First I convert all NaNs to 0 and make everything string
test = test.fillna(0)
test = test.astype(str)

然后我创建一个感兴趣的列的列表(这在这个例子中没有意义,因为只有 2 列,但在我的实际情况下有很多)

op = test.iloc[:,0:2].columns.tolist()

我本来以为我可以这样做:

test[op] = [1 if x != '0' else 0 for x in test[op]]

但它不起作用,因为它将所有内容都转换为 1。

然后我尝试手动执行每一列,它确实有效:

test['animal1'] = [1 if x != '0' else 0 for x in test['animal1']]

任何人都知道为什么后一种方式有效但不是前者?任何有关如何使其工作的指导将不胜感激。

编辑/更新:SeaBean 提供了一个可行的解决方案(谢谢!!)。我仍然很想知道为什么我使用的方法只在一次做一列(手动)时才有效。

标签: pythonpandas

解决方案


您可以使用 .isna() 并反转结果:

print(~test.isna())

   animal1  animal2  animal3  animal4
0    False     True     True     True
1     True     True     True     True
2     True    False     True     True
3    False    False     True     True

如果你宁愿有 0 和 1 乘以 1:

print((~test.isna())*1)

   animal1  animal2  animal3  animal4
0        0        1        1        1
1        1        1        1        1
2        1        0        1        1
3        0        0        1        1

推荐阅读