Вопрос или проблема
Это довольно простая задача, но я не могу найти ясного простого решения, кажется, что я что-то упускаю.
Допустим, у меня есть DataFrame следующего типа
df = pl.from_repr("""
┌───────┬───────┬───────┐
│ a ┆ b ┆ c │
│ --- ┆ --- ┆ --- │
│ bool ┆ bool ┆ bool │
╞═══════╪═══════╪═══════╡
│ false ┆ true ┆ false │
│ false ┆ false ┆ false │
│ false ┆ false ┆ false │
└───────┴───────┴───────┘
""")
Как я могу просто проверить, есть ли хотя бы одно значение True в DataFrame?
Некоторые решения, которые я нашел:
selection = df.select(pl.all().any(ignore_nulls=True))
или
selection = df.filter(pl.any_horizontal())
а затем проверить в этой строке
any(selection.row(0))
Кажется, что это слишком много шагов для одной проверки.
Эти два варианта немного короче и остаются в чистом Polars.
# Разворачиваем все булевы значения в единую колонку "value"
# Извлекаем колонку "value" в виде Series и выполняем операцию any
df.unpivot()["value"].any()
# pl.all().any() проверяет наличие значений True в каждой колонке
# pl.any_horizontal() проверяет горизонтально по строкам, сводя к единому значению
df.select(pl.any_horizontal(pl.all().any())).item()
К вашему вопросу:
Это довольно простая задача, но я не могу найти ясного простого решения, кажется, что я что-то упускаю. Кажется, что это слишком много шагов для одной проверки.
Вы ничего не упускаете. Причина, по которой это кажется немного более трудоемким, заключается в том, что DataFrame можно рассматривать больше как таблицу (базы данных). Обычно у вас есть разные колонки потенциально разных типов, и вы хотите проводить разные вычисления с разными колонками. Поэтому сведение обеих размерностей к единому значению в одном шаге не является тем, что обычно предлагается библиотеками DataFrame.
Numpy гораздо лучше подходит, если у вас есть матрицы, и предлагает это в одном шаге.
arr = df.to_numpy()
arr.any() # True
Если это только булевы колонки, вы можете использовать sum_horizontal()
+ sum()
bool(df.sum_horizontal().sum())
True
Используя
Сначала сворачиваем горизонтально, а затем вертикально:
df.select(pl.any_horizontal("*")).to_series().any()
True
Или сначала вертикально, а затем горизонтально:
df.select(pl.any_horizontal(pl.all().any())).item()
True
Если у вас только булевы значения, вы можете использовать
pl.DataFrame.max_horizontal()
для горизонтального сворачивания.pl.Expr.max()
для вертикального сворачивания.
df.max_horizontal().max()
True
Ответ или решение
Для проверки, есть ли хотя бы одно значение True
в DataFrame Polars, действительно существует несколько подходов, которые могут показаться немного сложными, но они тем не менее эффективны. Ниже я представлю различные методы, которые вы можете использовать для выполнения этой задачи.
-
Использование
pl.any_horizontal()
:
Этот метод позволяет проверить, есть ли хотя бы одно истинное значение в строках. Мы можем сначала применитьpl.any_horizontal()
для всех строк, а затем проверить, есть ли хотя бы одноTrue
среди этих результатов.import polars as pl df = pl.from_repr(""" ┌───────┬───────┬───────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ bool ┆ bool ┆ bool │ ╞═══════╪═══════╪═══════╡ │ false ┆ true ┆ false │ │ false ┆ false ┆ false │ │ false ┆ false ┆ false │ └───────┴───────┴───────┘ """) has_true = df.select(pl.any_horizontal("*")).to_series().any() print(has_true) # Вывод: True
-
Использование метода
max_horizontal()
иmax()
:
Если в вашем DataFrame только логические значения, вы можете использоватьmax_horizontal()
для сворачивания по строкам а затем применениеmax()
для сворачивания по столбцам.has_true = df.max_horizontal().max() print(has_true) # Вывод: True
-
Использование метода
sum_horizontal()
:
Если вы хотите использовать суммирование для проверки наличияTrue
, вы можете суммировать значения по строкам, а затем проверить, больше ли сумма нуля.has_true = bool(df.sum_horizontal().sum()) print(has_true) # Вывод: True
-
Использование приведения к NumPy:
Если вы хотите сделать это в одном шаге, вы можете преобразовать ваш DataFrame в массив NumPy и применить методany()
. Это также дает вам возможность работать с многомерными массивами.arr = df.to_numpy() has_true = arr.any() print(has_true) # Вывод: True
Заключение
Как вы видите, в Polars есть разные способы проверить, имеется ли хотя бы одно истинное значение в DataFrame. Хотя некоторые из них могут показаться более сложными, они обеспечивают гибкость и функциональность, которые могут быть полезны в различных сценариях. Выбор метода часто зависит от ваших предпочтений и структуры данных.