【问题标题】:Capturing presence of NAs in a new column for numeric columns在数字列的新列中捕获 NA 的存在
【发布时间】:2020-12-20 12:14:19
【问题描述】:

我有一个要在其上运行决策树建模的数据集。然而,数据集在数值列和分类列中都有 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']) 

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    进口

    import numpy as np
    import pandas as pd
    import math
    
    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']) 
    
    

    检查功能

    def func(x):
        if(math.isnan(x)):
            return 0;
        else:
            return 1;
    

    函数调用

    df2["value_1X_B"]=df2["Value1_X"].apply(func)
    

    输出

        ID  Value1_X    Class   Value2_X    value_1X_B
    0   1   33.0        Y       0.01        1
    1   2   101.0       N       0.05        1
    2   3   25.0        N       NaN         1
    3   4   245.0       N       NaN         1
    4   5   NaN         N       0.61        0
    

    【讨论】:

    • 这只是在指定的列中删除了带有 NA 的行,这不是我想要实现的。
    • 是的,它做到了!谢谢!无论如何要使函数调用循环遍历数据框中的列列表以获取每个数字变量的 NA 指示符列?我在原始数据集中有近 100 个数字列,它们的名称都以 _X 结尾。我将名称列表存储在这样的对象中:Num_cols = [col for col in df6.columns if '_X' in col]
    • 您可以将字典创建为:dictionary={"Value1_X":"Value_1X_B","Value2_X":"Value2_X_B"} 然后for keys,values in dictionary.items(): df2[values]=df2[keys].apply(func) 现在添加_B 的逻辑是基本的,您可以使用df2.columns 并使用循环在其中添加_B
    【解决方案2】:

    你可以试试这样的:

    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。

    【讨论】:

      猜你喜欢
      • 2020-12-04
      • 2023-01-11
      • 2014-11-04
      • 2020-06-27
      • 2016-09-20
      • 1970-01-01
      • 2021-08-19
      • 2021-05-07
      • 2018-03-03
      相关资源
      最近更新 更多