Отбрасывает столбец, если он превышает определенное количество значений NA

Я хочу написать программу, которая удаляет столбец, если он превышает определенное количество значений NA. Это то, что я сделал.

def check(x):
for column in df:
    if df.column.isnull().sum() > 2:
        df.drop(column,axis=1)

нет ошибки при выполнении вышеуказанного кода, но при выполнении df.apply(check)Есть куча ошибок.

PS: я знаю о аргументе молотить в df.dropna(thresh,axis)

Любые советы? Почему мой код не работает?

Спасибо

3 ответа

Решение

Я думаю, что лучше всего здесь использовать dropna с параметром thresh:

thresh: int, необязательный

Требуйте, чтобы многие не-NA значения.

Поэтому для векторизации решения вычтите его из длины DataFrame:

N = 2
df = df.dropna(thresh=len(df)-N, axis=1)
print (df)
   A  D    E  F
0  a  1  5.0  a
1  b  3  3.0  a
2  c  5  6.0  a
3  d  7  9.0  b
4  e  1  2.0  b
5  f  0  NaN  b

Я предлагаю использовать DataFrame.pipe для применения функции для ввода DataFrame с изменением df.column в df[column], потому что точечная нотация с динамическими именами столбцов из переменной не удалась (попробуйте выбрать имя столбца column):

df = pd.DataFrame({'A':list('abcdef'),
                   'B':[np.nan,np.nan,np.nan,5,5,np.nan],
                   'C':[np.nan,8,np.nan,np.nan,2,3],
                   'D':[1,3,5,7,1,0],
                   'E':[5,3,6,9,2,np.nan],
                   'F':list('aaabbb')})

print (df)
   A    B    C  D    E  F
0  a  NaN  NaN  1  5.0  a
1  b  NaN  8.0  3  3.0  a
2  c  NaN  NaN  5  6.0  a
3  d  5.0  NaN  7  9.0  b
4  e  5.0  2.0  1  2.0  b
5  f  NaN  3.0  0  NaN  b

def check(df):
    for column in df:
        if df[column].isnull().sum() > 2:
            df.drop(column,axis=1, inplace=True)
    return df

print (df.pipe(check))
   A  D    E  F
0  a  1  5.0  a
1  b  3  3.0  a
2  c  5  6.0  a
3  d  7  9.0  b
4  e  1  2.0  b
5  f  0  NaN  b

Хотя ответ Джезраэль работает, это не тот подход, который вы должны делать. Вместо этого создайте маску: ~df.isnull().sum().gt(2) и применить его с .loc[:,m] чтобы получить доступ к столбцам.

Полный пример:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'A':list('abcdef'),
    'B':[np.nan,np.nan,np.nan,5,5,np.nan],
    'C':[np.nan,8,np.nan,np.nan,2,3],
    'D':[1,3,5,7,1,0],
    'E':[5,3,6,9,2,np.nan],
    'F':list('aaabbb')
})

m = ~df.isnull().sum().gt(2)
df = df.loc[:,m]

print(df)

Возвращает:

   A  D    E  F
0  a  1  5.0  a
1  b  3  3.0  a
2  c  5  6.0  a
3  d  7  9.0  b
4  e  1  2.0  b
5  f  0  NaN  b

объяснение

Предположим, мы распечатываем столбцы и маску перед ее применением.

print(df.columns.tolist())
print(m.tolist())

Это вернуло бы это:

['A', 'B', 'C', 'D', 'E', 'F']
[True, False, False, True, True, True]

Столбцы B и C являются нежелательными (False). Они удаляются при наложении маски.

Кроме того, вы можете использовать count который считает ненулевые значения

In [23]: df.loc[:, df.count().gt(len(df.index) - 2)]
Out[23]:
   A  D    E  F
0  a  1  5.0  a
1  b  3  3.0  a
2  c  5  6.0  a
3  d  7  9.0  b
4  e  1  2.0  b
5  f  0  NaN  b
Другие вопросы по тегам