#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.