Polars – неожиданное поведение при использовании drop_nans() для всех столбцов

У меня есть простой фрейм данных Polars с некоторыми нулями и некоторыми NaN, и я хочу удалить только последнее. Я пытаюсь использовать drop_nans(), применяя его ко всем столбцам, и по какой-то причине он заменяет NaN на литерал 1.0.

Я в замешательстве. Возможно, я неправильно использую метод, но в документации мало информации и определенно не описывается такое поведение:

ex = pl.DataFrame(
    {
        'a': [float('nan'), 1, float('nan')],
        'b': [None, 'a', 'b']
    }
)

ex.with_columns(pl.all().drop_nans())

Out:

a   b
1.0 null
1.0 "a"
1.0 "b"

Я использую последнюю версию Polars 1.5.

Каков правильный способ перетаскивания NaN по всем столбцам, учитывая, что в кадрах данных Polars 1.5, похоже, нет метода drop_nans(), есть только у Series?

Обновлено: Я ожидаю, что результат должен быть:

a    b
1.0  'a'

Каков ожидаемый результат?

jqurious 28.08.2024 03:22

@jqurious, извини, я внес поправки в сообщение с ожидаемым результатом. Я ожидаю, что он должен удалить первую и последнюю строки данных.

NotAName 28.08.2024 03:24

Ах, ладно, так что это типа фильтр? df.filter(pl.col("a").is_not_nan())

jqurious 28.08.2024 03:26

@jqurious, ах да. Это сработает. Не думал использовать фильтр. Спасибо! Есть идеи, почему он заполняет значения 1.0, когда я использую drop_nans()?

NotAName 28.08.2024 03:29

Не уверен, что поведение drop_nans является «ошибкой» — из-за него у вас остается только 1.0 в a, например. df.select(pl.col("a").drop_nans()) но with_columns транслирует одно значение на всю длину кадра. В итоге у вас получится 1.0 3 раза. Не уверен, что вместо этого следует вызвать ShapeError. Он также не проверяет тип ввода: pl.col("b").is_nan() выдает ошибку TypeError, pl.col("b").drop_nans() молча «нет операций».

jqurious 28.08.2024 03:30

@jqurious, думаю, я подниму этот вопрос на их странице GitHub. Посмотрите, действительно ли это что-то, что нужно исправить.

NotAName 28.08.2024 03:35

Если вы измените свой пример на [float('nan'), 1, 2], появится ShapeError — так что я думаю, это подтверждает, что это ошибка.

jqurious 28.08.2024 04:10
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
7
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем примере происходит то, что drop_nans работает для каждого столбца. Сначала он преобразует серию [float('nan'), 1, float('nan')] в [1], а затем транслирует это значение на весь столбец в сочетании с ["a", "b"].

Это происходит потому, что в Polars пока нет концепции скалярного значения, и он будет рассматривать любой столбец с одним значением как таковой при принятии решения о том, когда транслировать. В будущем это изменится, но это большая работа. Итак, прямо сейчас вы можете увидеть подобные неправильные трансляции при использовании функций, фильтрующих столбцы, например drop_nan, если происходит фильтрация до столбца длиной 1.

Вместо того, чтобы делать pl.all().drop_nans(), вам следует фильтровать только те строки, в которых столбец a не имеет значения nan:

>>> df.filter(pl.col.a.is_not_nan())
shape: (1, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ f64 ┆ str │
╞═════╪═════╡
│ 1.0 ┆ a   │
└─────┴─────┘

Или, в более общем смысле, если у вас есть несколько столбцов со значениями с плавающей запятой:

>>> import polars.selectors as cs
>>> df.filter(pl.all_horizontal(cs.float().is_not_nan()))
shape: (1, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ f64 ┆ str │
╞═════╪═════╡
│ 1.0 ┆ a   │
└─────┴─────┘

Другие вопросы по теме