Фиксирование присутствия NAs в новом столбце для числовых столбцов

#python #pandas

#питон #панды

Вопрос:

У меня есть набор данных, для которого я хочу запустить моделирование дерева решений. Однако в наборе данных есть NAs как в числовых, так и в категориальных столбцах.

Для категориальных столбцов мое решение было простым, я использовал фиктивную кодировку с 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 )
 

Проблема связана с числовыми столбцами: Я не могу вменить среднее / медианное значение в NAs, поскольку отсутствие данных имеет значение. Я не могу приписать 0, поскольку это допустимое значение для столбцов. Я мог бы добавить что-то необычное, например -9999999.9, поскольку это был бы такой большой выброс, который мог бы отделить NAs от остальных числовых данных.

Но мне было интересно, есть ли какой-нибудь способ, которым я мог бы легко создать столбец для каждого числового столбца, который имел бы двоичный индикатор 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 в своих названиях. Есть ли способ автоматического создания столбцов индикатора NA для всех столбцов с _NUM в их имени, как я мог бы сделать для категориальных столбцов? И если имена столбцов индикатора 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']) 
 

Ответ №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
 

Комментарии:

1. Это просто отбросило строки с NAs в указанном столбце, чего я не пытался достичь.

2. Да, это так! Спасибо! Можно ли в любом случае выполнить цикл вызова функции по списку столбцов в dataframe, чтобы получить столбец индикатора NA для каждой числовой переменной? У меня около 100 числовых столбцов в исходном наборе данных, все они заканчиваются _X в конце их имени. Я сохраняю список имен в объекте, подобном этому: Num_cols = [col для col в df6.columns, если ‘_X’ в col]

3. вы можете создать словарь следующим образом: 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.