Невозможно вменить отсутствующие числовые значения

#python #pandas #missing-data #imputation

Вопрос:

Я хочу вменить недостающие значения как для числовых, так и для номинальных значений. Мой код для поиска отсутствующих числовых значений ничего не вернул, хотя один из столбцов HDI for year на самом деле имеет нулевые значения. Что не так с моим кодом?

 import numpy as np
import pandas as pd
import seaborn as sns; sns.set(style="ticks", color_codes=True)
from pandas.api.types import is_numeric_dtype

df.head()
country year    sex age suicides_no population  suicides/100k pop   country-year    HDI for year    gdp_for_year ($)    gdp_per_capita ($)  generation  year_label  sex_label   age_label   generation_label    is_duplicate
0   Albania 1987    male    15-24 years 21  312900  6.71    Albania1987 NaN 2156624900  796 Generation X    2   1   0   2   False
1   Albania 1987    male    35-54 years 16  308000  5.19    Albania1987 NaN 2156624900  796 Silent  2   1   2   5   False
2   Albania 1987    female  15-24 years 14  289700  4.83    Albania1987 NaN 2156624900  796 Generation X    2   0   0   2   False
3   Albania 1987    male    75  years   1   21800   4.59    Albania1987 NaN 2156624900  796 G.I. Generation 2   1   5   1   False
4   Albania 1987    male    25-34 years 9   274300  3.28    Albania1987 NaN 2156624900  796 Boomers 2   1   1   0   False
 

Проблемный код

 # Check if we have NaN numerical values
if is_numeric_dtype(df) is True:
    if df.isnull().any() is True:
        # Mean values of columns
        print(f"mean-df[i].column = {np.mean(df.column)}")
        # Impute
        df = df.fillna(df.mean())
 

Остальная часть кода, которая кажется прекрасной

 # Check for missing nominal data
else:
    for col in df.columns:
        if df[col].dtype == object:
            print(col, df[col].unique())
            print(f"mode-df[i], df[i].value_counts().index[0]")
            # Replace '?' with mode - value/level with highest frequency in the feature
            df[col] = df[col].replace({'?': 'df[i].value_counts().index[0]'})
 

Желаемый результат для вменения числовых значений.

 # Do we have NaN in our dataset?
df.isnull().any()

country               False
year                  False
sex                   False
age                   False
suicides_no           False
population            False
suicides/100k pop     False
country-year          False
HDI for year           True
gdp_for_year ($)      False
gdp_per_capita ($)    False
generation            False
year_label            False
sex_label             False
age_label             False
generation_label      False
is_duplicate          False
dtype: bool

print(f"mean-HDI-for-year= {np.mean(df['HDI for year'])}")

> mean-HDI-for-year= 0.7766011477761785

# Impute
df['HDI for year'] = df['HDI for year'].fillna(df['HDI for year'].mean())
 

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

1. Не используйте for loop для присвоения. Вы можете использовать df.select_dtypes("number") , если хотите получить числовые столбцы.

Ответ №1:

Как указано в комментариях, нет смысла использовать a for loop и перебирать ваши столбцы. Вы можете просто вменить свои числовые столбцы и категориальные столбцы отдельно, используя select_dtypes :

Предполагаемый DF :

 >>> df
   year  sex   age    income
0  2020    M  27.0   50000.0
1  2020    F   NaN       NaN
2  2020    M  29.0   20000.0
3  2020    F   NaN       NaN
4  2020  NaN  23.0   30000.0
5  2020  NaN  24.0       NaN
6  2020    M   NaN  100000.0

>>> df.isnull().sum()
year      0
sex       2
age       3
income    3
 

Вменяйте свои numeric колонки:

 >>> df.fillna(df.select_dtypes(include='number').mean(), inplace=True)
   year  sex    age    income
0  2020    M  27.00   50000.0
1  2020    F  25.75   50000.0
2  2020    M  29.00   20000.0
3  2020    F  25.75   50000.0
4  2020  NaN  23.00   30000.0
5  2020  NaN  24.00   50000.0
6  2020    M  25.75  100000.0
 

А затем ваши object колонки:

    year sex    age    income
0  2020   M  27.00   50000.0
1  2020   F  25.75   50000.0
2  2020   M  29.00   20000.0
3  2020   F  25.75   50000.0
4  2020   M  23.00   30000.0
5  2020   M  24.00   50000.0
6  2020   M  25.75  100000.0