【发布时间】:2018-01-12 21:04:26
【问题描述】:
我正在研究一个机器学习问题,其中特征中存在许多缺失值。有 100 个特征,我想删除那些缺失值太多的特征(它可能是缺失值超过 80% 的特征)。我如何在 Python 中做到这一点?
我的数据是 Pandas 数据框。
【问题讨论】:
标签: python pandas dataframe scikit-learn missing-data
我正在研究一个机器学习问题,其中特征中存在许多缺失值。有 100 个特征,我想删除那些缺失值太多的特征(它可能是缺失值超过 80% 的特征)。我如何在 Python 中做到这一点?
我的数据是 Pandas 数据框。
【问题讨论】:
标签: python pandas dataframe scikit-learn missing-data
演示:
设置:
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
【讨论】:
您可以使用 Pandas 的 dropna()。
limitPer = len(yourdf) * .80
yourdf = yourdf.dropna(thresh=limitPer, axis=1)
【讨论】:
在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
【讨论】:
要在 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)
【讨论】:
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
'''
【讨论】:
按列查找 NaN 总和或百分比的最快方法是:
【讨论】:
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)
【讨论】:
用途:
df = df[df.isnull().sum(axis=1) <= 5]
这里我们删除缺失值超过五个的行中的缺失值。
【讨论】:
根据文档,关于 dropna() 的一件事, thresh 参数指定要保留的非 NaN 的数量。
【讨论】: