首页 > 解决方案 > 在数字列的新列中捕获 NA 的存在

问题描述

我有一个要在其上运行决策树建模的数据集。然而,数据集在数值列和分类列中都有 NA。

对于分类列,我的解决方案很简单,我在整个分类列列表中使用了 dummy_na=True 的虚拟编码。我的所有专栏的名称中都包含 _CAT,因此它们很容易被捕获。

#get list of cat columns
cat_cols = [col for col in df5.columns if '_CAT' in col]
#dummy encode and capture NA presence
df_new = pd.get_dummies(df_old,dummy_na=True, columns = cat_cols )

问题出在数值列上:我无法将平均值/中位数归入 NA,因为缺少数据是有意义的。我无法估算 0,因为它是列的有效值。我可以输入一些时髦的东西,比如 -9999999.9,因为它会是一个非常大的异常值,它可能会将 NA 与其他数字数据区分开来。

但是我想知道是否有某种方法可以轻松地为每个数字列创建一个列,该列将具有二进制 1 或 0 指示符,以显示该数字列是否在其行中具有 NA。

所以如果我有这个:

  ID Value1_X Class Value2_X
0  1       33     Y     0.01
1  2      101     N     0.05
2  3       25     N      NaN
3  4      245     N      NaN
4  5      NaN     N     0.61
5  6    30000     Y      2.3

它变成了这样:

  ID Value1_X  Value1_NA Class Value2_X  Value2_NA
0  1       33          0     Y     0.01          0
1  2      101          0     N     0.05          0
2  3       25          0     N      NaN          1
3  4      245          0     N      NaN          1
4  5      NaN          1     N     0.61          0
5  6    30000          0     Y      2.3          0

此外,我所有的数字列的名称中都有 _NUM。有没有办法为名称中包含 _NUM 的所有列自动创建 NA 指示符列,就像我可以为分类列做的那样?如果 NA 指示符列名可以与上面示例中的数字列名有些匹配?

重新创建上述样本的数据:

data2 = [['1', 33,'Y',0.01], ['2', 101,'N',0.05],
        ['3', 25,'N',np.nan],['4', 245,'N',np.nan],
        ['5',np.nan ,'N',0.61], ['6', 30000,'Y',2.3]] 

df2 = pd.DataFrame(data2, columns = ['ID', 'Value1_X','Class','Value2_X']) 

data3 =  [['1', 33,0,'Y',0.01,0], 
          ['2', 101,0,'N',0.05,0],
        ['3', 25,0,'N','NaN',1],
        ['4', 245,0,'N','NaN',1],
        ['5','NaN',1 ,'N',0.61,0], 
        ['6', 30000,0,'Y',2.3,0]] 

df3 = pd.DataFrame(data3, columns = ['ID', 'Value1_X','Value1_NA','Class','Value2_X','Value2_NA']) 

标签: pythonpandas

解决方案


你可以尝试这样的事情:

data2 = [['1', 33,'Y',0.01], ['2', 101,'N',0.05],
        ['3', 25,'N',np.nan],['4', 245,'N',np.nan],
        ['5',np.nan ,'N',0.61], ['6', 30000,'Y',2.3]] 

df2 = pd.DataFrame(data2, columns = ['ID', 'Value1_X','Class','Value2_X'])

df2.assign(**df2.select_dtypes(include='number')
                .isna()
                .astype(int)
                .rename(columns=lambda x: x.split('_')[0]+'_NA'))

输出:

  ID  Value1_X Class  Value2_X  Value1_NA  Value2_NA
0  1      33.0     Y      0.01          0          0
1  2     101.0     N      0.05          0          0
2  3      25.0     N       NaN          0          1
3  4     245.0     N       NaN          0          1
4  5       NaN     N      0.61          1          0
5  6   30000.0     Y      2.30          0          0

注意:我修改了您的输入数据框,使“NaN”实际上是 np.nan,以使列的数据类型为浮点数而不是字符串/对象 dtypes。


推荐阅读