TL;DR
Мне хотелось бы иметь возможность кратко (с производительностью) фильтровать уникальность непрерывных строк, а не уникальность непрерывных строк.
Контекст
У меня есть LazyFrame с уже правильно упорядоченными данными. Хотя каждая строка данных всегда будет действительно уникальной во всех столбцах (с указанием времени), конкретное подмножество (столбцы), которое меня интересует, может иметь несмежные дубликаты, например:
┌─────┬──────┬─────────────────────────────────────────────┐
│ id ┆ data ┆ note │
│ --- ┆ --- ┆ --- │
│ i64 ┆ str ┆ str │
╞═════╪══════╪═════════════════════════════════════════════╡
│ 0 ┆ A ┆ new value (first time it's seen) │
│ 1 ┆ A ┆ contiguous duplicate │
│ 2 ┆ B ┆ new value │
│ 3 ┆ A ┆ non-contiguous duplicate of A which I want! │
│ 4 ┆ C ┆ new value │
│ 5 ┆ D ┆ new value │
└─────┴──────┴─────────────────────────────────────────────┘
При использовании Polars.LazyFrame.unique эти две разные серии A в 0-1 и 3 не могут использоваться в качестве уникальных проверок непрерывной (не непрерывной) уникальности. Я мог бы сохранить строку 0 или строку 3, а не (при использовании Keep='last') сказать строку 1 и строку 3.
Я решил эту проблему для следующего набора данных MRE, используя следующий код, но мне интересно, есть ли лучший способ. Строки с (хочу) (исключительно для иллюстрации) — это те, которые мне нужны. Идентификаторы строк предназначены для визуального поиска строк. Единственными реальными дискриминантами здесь являются столбцы foo, bar и baz.
Я решил эту проблему, добавляя значение маски 0 или 1 каждый раз, когда строка не совпадает с предыдущей (над нужными столбцами). Затем совокупное суммирование этого значения маски дает уникальное значение (внутри самого столбца маски), которое я могу использовать unique, чтобы сохранить несмежные повторяющиеся значения и удалить смежные.
pl.Config(tbl_rows=23, fmt_str_lengths=42) # increase repr defaults
df = pl.from_repr("""
┌─────┬─────┬─────┬─────┬──────────────────────────────────────┐
│ id ┆ foo ┆ bar ┆ baz ┆ nb │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 ┆ i64 ┆ str │
╞═════╪═════╪═════╪═════╪══════════════════════════════════════╡
│ a_1 ┆ 33 ┆ 33 ┆ 33 ┆ new (want) │
│ b_1 ┆ 22 ┆ 33 ┆ 33 ┆ new │
│ b_2 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup │
│ b_3 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup │
│ b_4 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup │
│ b_5 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup last (want) │
│ c_1 ┆ 22 ┆ 33 ┆ 22 ┆ new │
│ c_2 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup │
│ c_3 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup │
│ c_4 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup │
│ c_5 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup last (want) │
│ d_1 ┆ 22 ┆ 33 ┆ 33 ┆ new non-contig dup of b_1 etc (want) │
│ e_1 ┆ 22 ┆ 33 ┆ 22 ┆ new non-contig dup of c_1 etc (want) │
│ f_1 ┆ 22 ┆ 22 ┆ 22 ┆ new │
│ f_2 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup │
│ f_3 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup │
│ f_4 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup │
│ f_5 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup last (want) │
│ g_1 ┆ 11 ┆ 11 ┆ 11 ┆ new │
│ g_2 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup │
│ g_3 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup │
│ g_4 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup │
│ g_5 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup last (want) │
└─────┴─────┴─────┴─────┴──────────────────────────────────────┘
""")
Текущее решение:
(
df
# Construct the increment mask of 0 or 1.
.with_columns(
(
pl.col('foo').diff().cast(pl.Boolean) |
pl.col('bar').diff().cast(pl.Boolean) |
pl.col('baz').diff().cast(pl.Boolean)
).fill_null(True).cast(pl.Int32).alias('incr_grouping_mask')
)
# Cumulatively sum that mask.
.with_columns(
pl.col('incr_grouping_mask').cum_sum()
)
# Run unique over the cumulative sum of the mask.
.unique(
maintain_order=True,
subset='incr_grouping_mask',
keep='last'
)
)
Для получения правильного результата:
shape: (7, 6)
┌─────┬─────┬─────┬─────┬───────────────────────────────────┬────────────────────┐
│ id ┆ foo ┆ bar ┆ baz ┆ nb ┆ incr_grouping_mask │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 ┆ i64 ┆ str ┆ i32 │
╞═════╪═════╪═════╪═════╪═══════════════════════════════════╪════════════════════╡
│ a_1 ┆ 33 ┆ 33 ┆ 33 ┆ new (want) ┆ 1 │
│ b_5 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup last (want) ┆ 2 │
│ c_5 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup last (want) ┆ 3 │
│ d_1 ┆ 22 ┆ 33 ┆ 33 ┆ new non-contig dup of b_1 etc (w… ┆ 4 │
│ e_1 ┆ 22 ┆ 33 ┆ 22 ┆ new non-contig dup of c_1 etc (w… ┆ 5 │
│ f_5 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup last (want) ┆ 6 │
│ g_5 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup last (want) ┆ 7 │
└─────┴─────┴─────┴─────┴───────────────────────────────────┴────────────────────┘
Подробнее здесь: https://stackoverflow.com/questions/757 ... ess-filter
Фильтр несмежной уникальности Polars ⇐ Python
Программы на Python
1762117876
Anonymous
TL;DR
Мне хотелось бы иметь возможность кратко (с производительностью) фильтровать уникальность [b]непрерывных[/b] строк, а не уникальность [b]непрерывных[/b] строк.
Контекст
У меня есть LazyFrame с уже правильно упорядоченными данными. Хотя каждая строка данных всегда будет действительно уникальной во всех столбцах (с указанием времени), конкретное подмножество (столбцы), которое меня интересует, может иметь несмежные дубликаты, например:
┌─────┬──────┬─────────────────────────────────────────────┐
│ id ┆ data ┆ note │
│ --- ┆ --- ┆ --- │
│ i64 ┆ str ┆ str │
╞═════╪══════╪═════════════════════════════════════════════╡
│ 0 ┆ A ┆ new value (first time it's seen) │
│ 1 ┆ A ┆ contiguous duplicate │
│ 2 ┆ B ┆ new value │
│ 3 ┆ A ┆ non-contiguous duplicate of A which I want! │
│ 4 ┆ C ┆ new value │
│ 5 ┆ D ┆ new value │
└─────┴──────┴─────────────────────────────────────────────┘
При использовании Polars.LazyFrame.unique эти две разные серии A в 0-1 и 3 не могут использоваться в качестве уникальных проверок непрерывной (не непрерывной) уникальности. Я мог бы сохранить строку 0 [b]или[/b] строку 3, а не (при использовании Keep='last') сказать строку 1 [b]и[/b] строку 3.
Я решил эту проблему для следующего набора данных MRE, используя следующий код, но мне интересно, есть ли лучший способ. Строки с (хочу) (исключительно для иллюстрации) — это те, которые мне нужны. Идентификаторы строк предназначены для визуального поиска строк. Единственными реальными дискриминантами здесь являются столбцы foo, bar и baz.
Я решил эту проблему, добавляя значение маски 0 или 1 каждый раз, когда строка не совпадает с предыдущей (над нужными столбцами). Затем совокупное суммирование этого значения маски дает уникальное значение (внутри самого столбца маски), которое я могу использовать unique, чтобы сохранить несмежные повторяющиеся значения и удалить смежные.
pl.Config(tbl_rows=23, fmt_str_lengths=42) # increase repr defaults
df = pl.from_repr("""
┌─────┬─────┬─────┬─────┬──────────────────────────────────────┐
│ id ┆ foo ┆ bar ┆ baz ┆ nb │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 ┆ i64 ┆ str │
╞═════╪═════╪═════╪═════╪══════════════════════════════════════╡
│ a_1 ┆ 33 ┆ 33 ┆ 33 ┆ new (want) │
│ b_1 ┆ 22 ┆ 33 ┆ 33 ┆ new │
│ b_2 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup │
│ b_3 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup │
│ b_4 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup │
│ b_5 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup last (want) │
│ c_1 ┆ 22 ┆ 33 ┆ 22 ┆ new │
│ c_2 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup │
│ c_3 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup │
│ c_4 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup │
│ c_5 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup last (want) │
│ d_1 ┆ 22 ┆ 33 ┆ 33 ┆ new non-contig dup of b_1 etc (want) │
│ e_1 ┆ 22 ┆ 33 ┆ 22 ┆ new non-contig dup of c_1 etc (want) │
│ f_1 ┆ 22 ┆ 22 ┆ 22 ┆ new │
│ f_2 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup │
│ f_3 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup │
│ f_4 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup │
│ f_5 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup last (want) │
│ g_1 ┆ 11 ┆ 11 ┆ 11 ┆ new │
│ g_2 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup │
│ g_3 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup │
│ g_4 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup │
│ g_5 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup last (want) │
└─────┴─────┴─────┴─────┴──────────────────────────────────────┘
""")
Текущее решение:
(
df
# Construct the increment mask of 0 or 1.
.with_columns(
(
pl.col('foo').diff().cast(pl.Boolean) |
pl.col('bar').diff().cast(pl.Boolean) |
pl.col('baz').diff().cast(pl.Boolean)
).fill_null(True).cast(pl.Int32).alias('incr_grouping_mask')
)
# Cumulatively sum that mask.
.with_columns(
pl.col('incr_grouping_mask').cum_sum()
)
# Run unique over the cumulative sum of the mask.
.unique(
maintain_order=True,
subset='incr_grouping_mask',
keep='last'
)
)
Для получения правильного результата:
shape: (7, 6)
┌─────┬─────┬─────┬─────┬───────────────────────────────────┬────────────────────┐
│ id ┆ foo ┆ bar ┆ baz ┆ nb ┆ incr_grouping_mask │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 ┆ i64 ┆ str ┆ i32 │
╞═════╪═════╪═════╪═════╪═══════════════════════════════════╪════════════════════╡
│ a_1 ┆ 33 ┆ 33 ┆ 33 ┆ new (want) ┆ 1 │
│ b_5 ┆ 22 ┆ 33 ┆ 33 ┆ contig dup last (want) ┆ 2 │
│ c_5 ┆ 22 ┆ 33 ┆ 22 ┆ contig dup last (want) ┆ 3 │
│ d_1 ┆ 22 ┆ 33 ┆ 33 ┆ new non-contig dup of b_1 etc (w… ┆ 4 │
│ e_1 ┆ 22 ┆ 33 ┆ 22 ┆ new non-contig dup of c_1 etc (w… ┆ 5 │
│ f_5 ┆ 22 ┆ 22 ┆ 22 ┆ contig dup last (want) ┆ 6 │
│ g_5 ┆ 11 ┆ 11 ┆ 11 ┆ contig dup last (want) ┆ 7 │
└─────┴─────┴─────┴─────┴───────────────────────────────────┴────────────────────┘
Подробнее здесь: [url]https://stackoverflow.com/questions/75779811/polars-non-contiguous-uniqueness-filter[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия