Вопрос или проблема
Допустим, у меня есть данные, подобные этим:
import polars as pl
df = pl.DataFrame(
{
"subject": ["subject1", "subject2"],
"emails": [
["samATxyz.com", "janeATxyz.com", "jimATcustomer.org"],
["samATxyz.com", "zaneATxyz.com", "basATcustomer.org", "jimATcustomer.org"],
],
}
)
df
shape: (2, 2)
┌──────────┬─────────────────────────────────────────────────────────────────────────────┐
│ subject ┆ emails │
│ --- ┆ --- │
│ str ┆ list[str] │
╞══════════╪═════════════════════════════════════════════════════════════════════════════╡
│ subject1 ┆ ["samATxyz.com", "janeATxyz.com", "jimATcustomer.org"] │
│ subject2 ┆ ["samATxyz.com", "zaneATxyz.com", "basATcustomer.org", "jimATcustomer.org"] │
└──────────┴─────────────────────────────────────────────────────────────────────────────┘
Я хочу отфильтровать данные, чтобы в столбце emails содержались только электронные адреса, оканчивающиеся на "ATxyz.com"
.
shape: (2, 2)
┌──────────┬───────────────────────────────────┐
│ subject ┆ emails │
│ --- ┆ --- │
│ str ┆ list[str] │
╞══════════╪═══════════════════════════════════╡
│ subject1 ┆ ["samATxyz.com", "janeATxyz.com"] │
│ subject2 ┆ ["samATxyz.com", "zaneATxyz.com"] │
└──────────┴───────────────────────────────────┘
Как я могу сделать это, используя polars?
У меня было несколько идей, но я не могу разобраться с правильным синтаксисом, или кажется, что это более сложно/подробно, чем я ожидал:
- Может быть, я мог бы как-то отфильтровать данные, используя
.list.eval(pl.element() ...
, но я не могу понять, как отфильтровать элементы в списке с помощью этого синтаксиса. - Я мог бы изменить форму данных, используя
.explode
, но это кажется многословным и более сложным, чем нужно.
Это то, что я смог достичь
import polars as pl
df = pl.DataFrame(
{
"subject": ["subject1", "subject2"],
"emails": [
["samATxyz.com", "janeATxyz.com", "jimATcustomer.org"],
["samATxyz.com", "zaneATxyz.com", "basATcustomer.org", "jimATcustomer.org"],
],
}
)
df.with_columns(
pl.col("emails").list.eval(pl.element().str.contains("ATxyz")),
)
shape: (2, 2)
┌──────────┬────────────────────────────┐
│ subject ┆ emails │
│ --- ┆ --- │
│ str ┆ list[bool] │
╞══════════╪════════════════════════════╡
│ subject1 ┆ [true, true, false] │
│ subject2 ┆ [true, true, false, false] │
└──────────┴────────────────────────────┘
Вы были на правильном пути с pl.Expr.list.eval
. Это можно комбинировать с pl.Expr.filter
, чтобы добиться желаемого результата следующим образом.
df.with_columns(
pl.col("emails").list.eval(
pl.element().filter(pl.element().str.ends_with("ATxyz.com"))
)
)
shape: (2, 2)
┌──────────┬───────────────────────────────────┐
│ subject ┆ emails │
│ --- ┆ --- │
│ str ┆ list[str] │
╞══════════╪═══════════════════════════════════╡
│ subject1 ┆ ["samATxyz.com", "janeATxyz.com"] │
│ subject2 ┆ ["samATxyz.com", "zaneATxyz.com"] │
└──────────┴───────────────────────────────────┘
Ответ или решение
Чтобы отфильтровать список в столбце DataFrame с использованием библиотеки Polars, вы можете воспользоваться выражением pl.Expr.list.eval()
и комбинировать его с функцией pl.Expr.filter()
. Рассмотрим, как это сделать на примере ваших данных.
Предположим, у вас есть DataFrame с названием df
, который содержит два столбца: subject
и emails
. Столбец emails
включает в себя списки адресов электронной почты. Вы хотите отфильтровать этот столбец так, чтобы он содержал только адреса, оканчивающиеся на "ATxyz.com"
.
Вот как можно реализовать данный процесс:
import polars as pl
# Создание DataFrame
df = pl.DataFrame(
{
"subject": ["subject1", "subject2"],
"emails": [
["samATxyz.com", "janeATxyz.com", "jimATcustomer.org"],
["samATxyz.com", "zaneATxyz.com", "basATcustomer.org", "jimATcustomer.org"],
],
}
)
# Применение фильтрации к списку в столбце emails
filtered_df = df.with_columns(
pl.col("emails").list.eval(
pl.element().filter(pl.element().str.ends_with("ATxyz.com"))
)
)
# Вывод отфильтрованного DataFrame
print(filtered_df)
При выполнении вышеуказанного кода вы получите следующий вывод:
shape: (2, 2)
┌──────────┬───────────────────────────────────┐
│ subject ┆ emails │
│ --- ┆ --- │
│ str ┆ list[str] │
╞══════════╪═══════════════════════════════════╡
│ subject1 ┆ ["samATxyz.com", "janeATxyz.com"] │
│ subject2 ┆ ["samATxyz.com", "zaneATxyz.com"] │
└──────────┴───────────────────────────────────┘
Таким образом, столбец emails
теперь содержит только те адреса, которые заканчиваются на ATxyz.com
.
Объяснение:
pl.col("emails")
выбирает столбецemails
..list.eval(...)
применяет функцию к каждому списку в этом столбце.pl.element().filter(...)
позволяет фильтровать элементы списка на основе условия, установленного вpl.element().str.ends_with("ATxyz.com")
, что проверяет, оканчивается ли каждый адрес электронной почты на указанный домен.
Эта методология является простой и эффективной для выполнения нужной фильтрации в данных Polars.