1

我有一列缺少分类数据,我试图用同一列中的现有分类变量替换它们。

我不想使用该模式,因为我有太多丢失的数据,它会扭曲数据,我宁愿不删除丢失数据的行。

我认为理想的方法是获取我的列中每个变量的比例,然后用现有的分类变量按比例替换缺失的变量。

示例数据框:

   ClientId    Apple_cat    Region    Price
0  21          cat_1        Reg_A     5
1  15          cat_2        Nan       6
2  6           Nan          Reg_B     7
3  91          cat_3        Reg_A     3
4  45          Nan          Reg_C     7
5  89          cat_2        Nan       6

注意:理想情况下,我想避免对每个类别和区域名称进行硬编码。

4

3 回答 3

2

你可以滚动你自己的函数,以一种简洁的矢量化方法来解决这个问题:

def na_randomfill(series):
    na_mask = pd.isnull(series)   # boolean mask for null values
    n_null = na_mask.sum()        # number of nulls in the Series
    
    if n_null == 0:
        return series             # if there are no nulls, no need to resample
    
    # Randomly sample the non-null values from our series
    #  only sample this Series as many times as we have nulls 
    fill_values = series[~na_mask].sample(n=n_null, replace=True, random_state=0)

    # This ensures our new values will replace NaNs in the correct locations
    fill_values.index = series.index[na_mask]
    
    return series.fillna(fill_values) 

此解决方案一次适用于 1 系列,可以这样调用:

out = na_randomfill(df["Apple_cat"])

print(out)
0    cat_1
1    cat_2
2    cat_3
3    cat_3
4    cat_2
5    cat_2
Name: Apple_cat, dtype: object

或者,您可以使用 apply 在每个列上调用它。请注意,由于if我们函数中的语句,我们不需要在调用之前提前指定包含空的列apply

out = df.apply(na_randomfill)

print(out)
   ClientId Apple_cat Region  Price
0        21     cat_1  Reg_A      5
1        15     cat_2  Reg_A      6
2         6     cat_3  Reg_B      7
3        91     cat_3  Reg_A      3
4        45     cat_2  Reg_C      7
5        89     cat_2  Reg_C      6
于 2020-10-22T16:08:21.407 回答
0

在 pandas Dataframe 中替换 NaN 的难点在于 fillna() 方法将用相同的数字替换所有 nan,即使您在调用中添加了某种随机性。

import random
df['Apple_cat'].applymap(lambda x: x if not np.isnan(x) else np.random.choice(random.choice(list(x.dropna(axis=0))))

这将用来自第 th 列其余部分的随机样本替换 Nans。也许您需要将 np.nan 替换为其他类型的 nan。

于 2020-10-22T15:58:13.757 回答
0

您可以根据填充行的概率分布来填充缺失值。

import numpy as np

df[‘<your_column_name>’] = df[‘<your_column_name>’].fillna(‘TBD’)
possible_values = df[‘<your_column_name>’].value_counts().to_dict()

possible_values.pop(‘TBD’)
total_items = sum(possible_values.keys())
possible_values = [(k,v) for k,v in possible_values.items()]
prob_dist = [i[1]/total_items for i in possible_values]

def fill_missing_values(item):
    if item != ‘TBD’:
        index = np.random.choice(np.arange(len(prob_dist), p=prob_dist)
        return possible_values[index]
    return item

df[‘<your_column_name>’] = df[‘<your_column_name>’].apply(lambda x: fill_missing_values(x))
于 2020-10-22T15:59:33.127 回答