Панды: удалить столбцы со всеми NaN

Я понимаю, что удалить NaN из фрейма данных так же просто, как df.dropna, но по какой-то причине это не работает на моем, и я не уверен, почему.

Вот мой оригинальный фрейм данных:

fish_frame1:                       0   1   2         3   4       5   6          7
0               #0915-8 NaN NaN       NaN NaN     NaN NaN        NaN
1                   NaN NaN NaN  LIVE WGT NaN  AMOUNT NaN      TOTAL
2               GBW COD NaN NaN     2,280 NaN   $0.60 NaN  $1,368.00
3               POLLOCK NaN NaN     1,611 NaN   $0.01 NaN     $16.11
4                 WHAKE NaN NaN       441 NaN   $0.70 NaN    $308.70
5           GBE HADDOCK NaN NaN     2,788 NaN   $0.01 NaN     $27.88
6           GBW HADDOCK NaN NaN    16,667 NaN   $0.01 NaN    $166.67
7               REDFISH NaN NaN       932 NaN   $0.01 NaN      $9.32
8    GB WINTER FLOUNDER NaN NaN       145 NaN   $0.25 NaN     $36.25
9   GOM WINTER FLOUNDER NaN NaN    25,070 NaN   $0.35 NaN  $8,774.50
10        GB YELLOWTAIL NaN NaN        26 NaN   $1.75 NaN     $45.50

Следующий код представляет собой попытку удалить все NaN, а также любые столбцы с более чем 3 NaN (я думаю, должен работать либо один, либо оба):

fish_frame.dropna()
fish_frame.dropna(thresh=len(fish_frame) - 3, axis=1)

Это производит:

fish_frame1 after dropna:                       0   1   2         3   4       5   6          7
0               #0915-8 NaN NaN       NaN NaN     NaN NaN        NaN
1                   NaN NaN NaN  LIVE WGT NaN  AMOUNT NaN      TOTAL
2               GBW COD NaN NaN     2,280 NaN   $0.60 NaN  $1,368.00
3               POLLOCK NaN NaN     1,611 NaN   $0.01 NaN     $16.11
4                 WHAKE NaN NaN       441 NaN   $0.70 NaN    $308.70
5           GBE HADDOCK NaN NaN     2,788 NaN   $0.01 NaN     $27.88
6           GBW HADDOCK NaN NaN    16,667 NaN   $0.01 NaN    $166.67
7               REDFISH NaN NaN       932 NaN   $0.01 NaN      $9.32
8    GB WINTER FLOUNDER NaN NaN       145 NaN   $0.25 NaN     $36.25
9   GOM WINTER FLOUNDER NaN NaN    25,070 NaN   $0.35 NaN  $8,774.50
10        GB YELLOWTAIL NaN NaN        26 NaN   $1.75 NaN     $45.50

Я новичок в Pandas, поэтому я не уверен, что это не работает, потому что я делаю что-то неправильно, или я что-то неправильно понимаю, или неправильно использую команду. Любая помощь приветствуется, спасибо.


person theprowler    schedule 17.07.2017    source источник
comment
.dropna() не изменяет DF на месте - он возвращает измененный DF... поэтому вам нужно либо вернуть его обратно, например: df = df.dropna(), либо явно использовать параметр inplace=True   -  person MaxU    schedule 17.07.2017
comment
О, мой плохой. Попался. Должен ли я ожидать, что эта команда создаст пустой фрейм данных, учитывая, сколько NaN у моего исходного?   -  person theprowler    schedule 17.07.2017
comment
я думаю, что ваша вторая команда должна работать (поскольку она нацелена на столбцы), но первая удалит любую строку с NaN - поскольку во всех строках есть хотя бы один NaN, она удалит их все.   -  person Corley Brigman    schedule 17.07.2017
comment
@MaxU: лучше сказать dropna() по умолчанию делает inplace=False, поэтому вам нужно будет назначить это; но если вы хотите на месте, просто сделайте dropna(..., inplace=True)   -  person smci    schedule 10.09.2019
comment
OP Когда вы говорите удалить все столбцы NaN, вы на самом деле имеете в виду удалить все столбцы NaN. Это немного другое.   -  person smci    schedule 10.09.2019
comment
Почти дублированный, но более старый вопрос 2012 года ?. К сожалению, мы не можем закрыть это в этом. Также с 2015 г. Фрейм данных pandas, в котором не все указанные столбцы являются NaN   -  person smci    schedule 10.09.2019


Ответы (4)


Из строки документации dropna:

Отбросьте столбцы, в которых все элементы имеют значение NaN:
df.dropna(axis=1, how='all')


   A    B    D
0  NaN  2.0  0
1  3.0  4.0  1
2  NaN  NaN  5
person Corley Brigman    schedule 17.07.2017

dropna() отбрасывает нулевые значения и возвращает dataFrame. Назначьте его обратно исходному фрейму данных.

fish_frame = fish_frame.dropna(axis = 1, how = 'all')

Ссылаясь на ваш код:

fish_frame.dropna(thresh=len(fish_frame) - 3, axis=1)

Это приведет к удалению столбцов с 7 или более NaN (при условии, что len (df) = 10), если вы хотите удалить столбцы с более чем 3 NaN, как вы упомянули, thresh должен быть равен 3.

person Rakesh Adhikesavan    schedule 17.07.2017
comment
Верно. MaxU объяснил, почему это работает. Но конкретно для моего фрейма данных он создал пустой фрейм данных после запуска fish_frame = fish_frame.dropna(). Этого следует ожидать? - person theprowler; 17.07.2017
comment
попробуйте передать параметр how = 'all' - person Rakesh Adhikesavan; 17.07.2017

dropna() по умолчанию возвращает фрейм данных (по умолчанию поведение inplace=False), и поэтому его необходимо назначить новому фрейму данных, чтобы он оставался в вашем коде.

Так, например,

fish_frame = fish_frame.dropna()

Что касается того, почему ваш dropna возвращает пустой фрейм данных, я бы рекомендовал вам взглянуть на аргумент «как» в методе dropna (https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html). Также имейте в виду, что ось = 0 соответствует столбцам, а ось = 1 соответствует строкам.

Таким образом, чтобы удалить столбцы со всеми «NA», ось = 0, как = «любой» должен сделать свое дело:

fish_frame = fish_frame.dropna(axis=0, how="any")

Наконец, аргумент «thresh» явно указывает, сколько NA необходимо для отбрасывания. Так

fish_frame = fish_frame.dropna(axis=0, thresh=3, how="any") 

должен работать нормально и денди, чтобы удалить любой столбец с тремя NA.

Кроме того, как указал Корли, по умолчанию используется параметр how="any" и, следовательно, в нем нет необходимости.

person SeeDerekEngineer    schedule 17.07.2017

Другим решением было бы создать логический фрейм данных со значениями True в ненулевых позициях, а затем взять столбцы, имеющие хотя бы одно значение True. Строка ниже удаляет столбцы со всеми значениями NaN.

df = df.loc[:,df.notna().any(axis=0)]

Если вы хотите удалить столбцы, имеющие хотя бы одно отсутствующее значение (NaN);

df = df.loc[:,df.notna().all(axis=0)]

Этот подход особенно полезен при удалении столбцов, содержащих пустые строки, нули или любое заданное значение. Например;

df = df.loc[:,(df!='').all(axis=0)]

удаляет столбцы, имеющие хотя бы одну пустую строку.

person Achintha Ihalage    schedule 12.05.2021