У меня есть простой фрейм данных 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, извини, я внес поправки в сообщение с ожидаемым результатом. Я ожидаю, что он должен удалить первую и последнюю строки данных.
Ах, ладно, так что это типа фильтр? df.filter(pl.col("a").is_not_nan())
@jqurious, ах да. Это сработает. Не думал использовать фильтр. Спасибо! Есть идеи, почему он заполняет значения 1.0, когда я использую drop_nans()
?
Не уверен, что поведение 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, думаю, я подниму этот вопрос на их странице GitHub. Посмотрите, действительно ли это что-то, что нужно исправить.
Если вы измените свой пример на [float('nan'), 1, 2]
, появится ShapeError
— так что я думаю, это подтверждает, что это ошибка.
В вашем примере происходит то, что 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 │
└─────┴─────┘
Каков ожидаемый результат?