Для некоторых столбцов df
, если 80% столбца - NAN
.
Какой самый простой код для удаления таких столбцов?
Для некоторых столбцов df
, если 80% столбца - NAN
.
Какой самый простой код для удаления таких столбцов?
Вы можете использовать isnull
со mean
для treshold, а затем удалить столбцы с помощью boolean indexing
с помощью loc
(поскольку удалить столбцы), также необходимо условие инвертирования - поэтому <.8
означает удаление всех столбцов >=0.8
:
df = df.loc[:, df.isnull().mean() < .8]
Образец:
np.random.seed(100)
df = pd.DataFrame(np.random.random((100,5)), columns=list('ABCDE'))
df.loc[:80, 'A'] = np.nan
df.loc[:5, 'C'] = np.nan
df.loc[20:, 'D'] = np.nan
print (df.isnull().mean())
A 0.81
B 0.00
C 0.06
D 0.80
E 0.00
dtype: float64
df = df.loc[:, df.isnull().mean() < .8]
print (df.head())
B C E
0 0.278369 NaN 0.004719
1 0.670749 NaN 0.575093
2 0.209202 NaN 0.219697
3 0.811683 NaN 0.274074
4 0.940030 NaN 0.175410
Если хотите удалить столбцы с минимальными значениями dropna
работающими с параметром thresh
и axis=1
для удаления столбцов:
np.random.seed(1997)
df = pd.DataFrame(np.random.choice([np.nan,1], p=(0.8,0.2),size=(10,10)))
print (df)
0 1 2 3 4 5 6 7 8 9
0 NaN NaN NaN 1.0 1.0 NaN NaN NaN NaN NaN
1 1.0 NaN 1.0 NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN 1.0 1.0 NaN NaN NaN
3 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN 1.0 NaN NaN NaN 1.0
5 NaN NaN NaN 1.0 1.0 NaN NaN 1.0 NaN 1.0
6 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN
9 1.0 NaN NaN NaN 1.0 NaN NaN 1.0 NaN NaN
df1 = df.dropna(thresh=2, axis=1)
print (df1)
0 3 4 5 7 9
0 NaN 1.0 1.0 NaN NaN NaN
1 1.0 NaN NaN NaN NaN NaN
2 NaN NaN NaN 1.0 NaN NaN
3 NaN NaN 1.0 NaN NaN NaN
4 NaN NaN NaN 1.0 NaN 1.0
5 NaN 1.0 1.0 NaN 1.0 1.0
6 NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN 1.0 NaN
9 1.0 NaN 1.0 NaN 1.0 NaN
EDIT: для небулевых данных
Общее количество записей NaN в столбце должно составлять менее 80% от общего числа записей:
df = df.loc[:, df.isnull().sum() < 0.8*df.shape[0]]
Как указано в комментариях, если вы используете sum()
для логического теста, вы можете получить количество вхождений.
Код:
def get_nan_cols(df, nan_percent=0.8):
threshold = len(df.index) * nan_percent
return [c for c in df.columns if sum(df[c].isnull()) >= threshold]
Используется в качестве:
del df[get_nan_cols(df, 0.8)]
df.dropna(thresh=np.int((100-percent_NA_cols_required)*(len(df.columns)/100)),inplace=True)
В основном pd.dropna принимает число (int) не_значных столбцов, необходимых для удаления этой строки.
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
'''