如何在 Python 中删除缺失值过多的列

Posted

技术标签:

【中文标题】如何在 Python 中删除缺失值过多的列【英文标题】:How to remove columns with too many missing values in Python 【发布时间】:2018-01-12 21:04:26 【问题描述】:

我正在研究一个机器学习问题,其中特征中存在许多缺失值。有 100 个特征,我想删除那些缺失值太多的特征(它可能是缺失值超过 80% 的特征)。我如何在 Python 中做到这一点?

我的数据是 Pandas 数据框。

【问题讨论】:

【参考方案1】:

演示:

设置:

In [105]: df = pd.DataFrame(np.random.choice([2,np.nan], (20, 5), p=[0.2, 0.8]), columns=list('abcde'))

In [106]: df
Out[106]:
      a    b    c    d    e
0   NaN  2.0  NaN  NaN  NaN
1   NaN  NaN  2.0  NaN  2.0
2   NaN  2.0  NaN  NaN  NaN
3   NaN  NaN  NaN  NaN  2.0
4   NaN  2.0  2.0  NaN  NaN
5   NaN  NaN  NaN  NaN  NaN
6   NaN  2.0  NaN  NaN  NaN
7   2.0  2.0  NaN  NaN  NaN
8   2.0  2.0  NaN  NaN  NaN
9   NaN  NaN  NaN  NaN  NaN
10  NaN  2.0  2.0  NaN  2.0
11  NaN  NaN  NaN  2.0  NaN
12  2.0  NaN  NaN  2.0  NaN
13  NaN  NaN  NaN  2.0  NaN
14  NaN  NaN  NaN  2.0  2.0
15  NaN  NaN  NaN  NaN  NaN
16  NaN  2.0  NaN  NaN  NaN
17  2.0  NaN  NaN  NaN  2.0
18  NaN  NaN  NaN  2.0  NaN
19  NaN  2.0  NaN  2.0  NaN

In [107]: df.isnull().mean()
Out[107]:
a    0.80
b    0.55
c    0.85
d    0.70
e    0.75
dtype: float64

解决方案:

In [108]: df.columns[df.isnull().mean() < 0.8]
Out[108]: Index(['b', 'd', 'e'], dtype='object')

In [109]: df[df.columns[df.isnull().mean() < 0.8]]
Out[109]:
      b    d    e
0   2.0  NaN  NaN
1   NaN  NaN  2.0
2   2.0  NaN  NaN
3   NaN  NaN  2.0
4   2.0  NaN  NaN
5   NaN  NaN  NaN
6   2.0  NaN  NaN
7   2.0  NaN  NaN
8   2.0  NaN  NaN
9   NaN  NaN  NaN
10  2.0  NaN  2.0
11  NaN  2.0  NaN
12  NaN  2.0  NaN
13  NaN  2.0  NaN
14  NaN  2.0  2.0
15  NaN  NaN  NaN
16  2.0  NaN  NaN
17  NaN  NaN  2.0
18  NaN  2.0  NaN
19  2.0  2.0  NaN

【讨论】:

一如既往的出色解决方案,+1。但是,为了可见性,我会说最好有更多的列而不是行。我也添加了一个行过滤器作为答案。 (或者也许只是我 - 坐在笔记本电脑上)【参考方案2】:

您可以使用 Pandas 的 dropna()

limitPer = len(yourdf) * .80
yourdf = yourdf.dropna(thresh=limitPer, axis=1)

【讨论】:

更熊猫风格的解决方案!【参考方案3】:

在MaxU's example之后,这是过滤行的选项:

    df = pd.DataFrame(np.random.choice([2,np.nan], (5,10), p=[0.2, 0.8]), columns=list('abcdefghij'))
        a    b    c    d    e    f    g    h    i    j
    0   NaN  NaN  NaN  NaN  NaN  2.0  NaN  NaN  NaN  2.0
    1   NaN  2.0  NaN  2.0  NaN  NaN  2.0  NaN  NaN  2.0
    2   NaN  NaN  2.0  NaN  2.0  NaN  2.0  2.0  NaN  NaN
    3   NaN  NaN  NaN  NaN  NaN  2.0  NaN  NaN  NaN  2.0
    4   2.0  2.0  2.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN

    df.loc[df.isnull().mean(axis=1).lt(0.8)]
        a    b    c    d    e    f    g    h    i    j
    1   NaN  2.0  NaN  2.0  NaN  NaN  2.0  NaN  NaN  2.0
    2   NaN  NaN  2.0  NaN  2.0  NaN  2.0  2.0  NaN  NaN
    4   2.0  2.0  2.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN

【讨论】:

【参考方案4】:

要在 Pandas 中进行概括,您可以执行以下操作来计算缺少值的列中值的百分比。您可以从这些列中过滤掉 NULL 值超过 80% 的特征,然后从 DataFrame 中删除这些列。

pct_null = df.isnull().sum() / len(df)
missing_features = pct_null[pct_null > 0.80].index
df.drop(missing_features, axis=1, inplace=True)

【讨论】:

【参考方案5】:

这是一个简单的函数,您可以通过传递数据帧和阈值直接使用它

def rmissingvaluecol(dff, threshold):
    l = []
    l = list(dff.drop(dff.loc[:,list((100*(dff.isnull().sum()/len(dff.index)) >= threshold))].columns, 1).columns.values)
    print("# Columns having more than %s percent missing values: "%threshold, (dff.shape[1] - len(l)))
    print("Columns:\n", list(set(list((dff.columns.values))) - set(l)))
    return l


rmissingvaluecol(df,80) # Here threshold is 80% which means we are going to drop columns having more than 80% of missing values

# Output
'''
# Columns having more than 60 percent missing values: 2
Columns:
 ['id', 'location']
'''

现在创建一个不包括这些列的新数据框:

l = rmissingvaluecol(df, 49)
df1 = df[l]

奖励步骤

您可以找到每列缺失值的百分比(可选)

def missing(dff):
    print (round((dff.isnull().sum() * 100/ len(dff)),2).sort_values(ascending=False))

missing(df)

# Output
'''
id          83.33
location    83.33
owner       16.67
pets        16.67
dtype: float64
'''

【讨论】:

【参考方案6】:

按列查找 NaN 总和或百分比的最快方法是:

求和:df.isna().sum() 对于百分比:df.isna().mean()

【讨论】:

【参考方案7】:
def show_null_columns(data, agg, threshold):
    if agg == 'sum':
       null_cols = data.isnull().sum()
    elif agg == 'mean':
       null_cols = data.isnull().mean()
    columns = data.columns
    null_dic = 
    for col,x in zip(columns, null_cols):
        if x>= threshold:
            null_dic[col] = x
    return null_dic

null_dic = show_null_columns(train, 'mean', 0.8)
train2 = train.drop(null_dic.keys(), axis=1)

【讨论】:

【参考方案8】:

用途:

df = df[df.isnull().sum(axis=1) <= 5]

这里我们删除缺失值超过五个的行中的缺失值。

【讨论】:

【参考方案9】:

根据文档,关于 dropna() 的一件事, thresh 参数指定要保留的非 NaN 的数量。

【讨论】:

欢迎来到 ***。这似乎更像是评论而不是答案。请考虑评论您最喜欢的答案。 我确实尝试过,但我似乎还没有足够的“声誉”。但是,我认为我提到的这一点可以改变 dropna() 的输出。 坚持住。用不了多久你就可以制作 cmets 了。 感谢您的鼓励!

以上是关于如何在 Python 中删除缺失值过多的列的主要内容,如果未能解决你的问题,请参考以下文章

R语言ggplot2可视化:计算dataframe中每个数据列缺失值的个数使用堆叠的条形图(Stacked Barplot)可视化每个数据列的缺失值的情况(自定义堆叠条形图的形式)

缺失值处理

pandas使用dropna函数删除dataframe中列缺失值的个数大于某一比例阈值的数据列

机器学习1:数据预处理

计算数据帧 Spark 中缺失值的数量

如何在 Python 中删除缺失值过多的列