Предотвратить совпадение значений «None» с «is_in» Polars.Python

Программы на Python
Ответить
Anonymous
 Предотвратить совпадение значений «None» с «is_in» Polars.

Сообщение Anonymous »

Как избежать совпадения None при сравнении значений в двух разных кадрах данных Polars? Обработка равенства None кажется противоречивой при использовании is_in и join.
Например, если я начну с фреймов данных main_pl (со всеми записями) и sub_pl (с подмножеством записей):

Код: Выделить всё

import polars as pl

r1 = {"foo":"a", "bar":"b", "baz":"c"}
r2 = {"foo":"x", "bar":"y", "baz":"z"}
r3 = {"foo":"a", "bar":"b", "baz":None}
r4 = {"foo":"m", "bar":"n", "baz":"o"}
r5 = {"foo":"x", "bar":"y", "baz":None}
r6 = {"foo":"a", "bar":"b", "baz":None}

all_records = [r1, r2, r3, r4, r5, r6]
sub_records = [r1, r2, r3]

target_cols = ["foo", "bar", "baz"]

main_pl = pl.DataFrame(all_records)
sub_pl = pl.DataFrame(sub_records)
main_pl:

Код: Выделить всё

shape: (6, 3)

┌─────┬─────┬──────┐
│ foo ┆ bar ┆ baz  │
│ --- ┆ --- ┆ ---  │
│ str ┆ str ┆ str  │
╞═════╪═════╪══════╡
│ a   ┆ b   ┆ c    │
│ x   ┆ y   ┆ z    │
│ a   ┆ b   ┆ null │
│ m   ┆ n   ┆ o    │
│ x   ┆ y   ┆ null │
│ a   ┆ b   ┆ null │
└─────┴─────┴──────┘
и строки for_matching из sub_pl:

Код: Выделить всё

shape: (3, 3)
┌─────┬─────┬──────┐
│ foo ┆ bar ┆ baz  │
│ --- ┆ --- ┆ ---  │
│ str ┆ str ┆ str  │
╞═════╪═════╪══════╡
│ a   ┆ b   ┆ c    │
│ x   ┆ y   ┆ z    │
│ a   ┆ b   ┆ null │
└─────┴─────┴──────┘

Код: Выделить всё

for_matching = sub_pl.select(
pl.struct(pl.col(target_cols)).alias("for_matching")
).get_column("for_matching")
for_matching

Код: Выделить всё

shape: (3,)
Series: 'for_matching' [struct[3]]
[
{"a","b","c"}
{"x","y","z"}
{"a","b",null}
]
1. При сравнении значений «Нет» является ли разница в поведении по умолчанию между is_in и join противоречивой или есть причина или способ контролировать то, что кажется разными результатами?
--- is_in

Код: Выделить всё

main_pl.with_columns(
pl.struct(pl.all()).is_in(for_matching.implode()).alias("matched"))

Код: Выделить всё

shape: (6, 4)
┌─────┬─────┬──────┬─────────┐
│ foo ┆ bar ┆ baz  ┆ matched │
│ --- ┆ --- ┆ ---  ┆ ---     │
│ str ┆ str ┆ str  ┆ bool    │
╞═════╪═════╪══════╪═════════╡
│ a   ┆ b   ┆ c    ┆ true    │
│ x   ┆ y   ┆ z    ┆ true    │
│ a   ┆ b   ┆ null ┆ true    │
│ m   ┆ n   ┆ o    ┆ false   │
│ x   ┆ y   ┆ null ┆ false   │
│ a   ┆ b   ┆ null ┆ true    │
└─────┴─────┴──────┴─────────┘
--- присоединяйтесь

Код: Выделить всё

main_pl.join(sub_pl, on=target_cols)

Код: Выделить всё

shape: (2, 3)
┌─────┬─────┬─────┐
│ foo ┆ bar ┆ baz │
│ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str │
╞═════╪═════╪═════╡
│ a   ┆ b   ┆ c   │
│ x   ┆ y   ┆ z   │
└─────┴─────┴─────┘
2. Есть ли способ заставить поляры is_in работать аналогично методам pandas isin при сравнении значений None?

Код: Выделить всё

import pandas as pd

main_pd = pd.DataFrame(all_records)
sub_pd = pd.DataFrame(sub_records)

main_pd["matched_w_none"] = main_pd[target_cols].isin(sub_pd).all(1)
pl.from_pandas(main_pd)

Код: Выделить всё

shape: (6, 4)
┌─────┬─────┬──────┬────────────────┐
│ foo ┆ bar ┆ baz  ┆ matched_w_none │
│ --- ┆ --- ┆ ---  ┆ ---            │
│ str ┆ str ┆ str  ┆ bool           │
╞═════╪═════╪══════╪════════════════╡
│ a   ┆ b   ┆ c    ┆ true           │
│ x   ┆ y   ┆ z    ┆ true           │
│ a   ┆ b   ┆ null ┆ false          │
│ m   ┆ n   ┆ o    ┆ false          │
│ x   ┆ y   ┆ null ┆ false          │
│ a   ┆ b   ┆ null ┆ false          │
└─────┴─────┴──────┴────────────────┘
В конечном итоге я пытаюсь добиться тех же результатов с помощью поляров, которые я получаю по умолчанию с помощью pandas при сравнении строк из разных фреймов данных, где могут присутствовать значения None.

Подробнее здесь: https://stackoverflow.com/questions/796 ... lars-is-in
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»