Найдите все различия между группами в кадре данных Polars.Python

Программы на Python
Anonymous
Найдите все различия между группами в кадре данных Polars.

Сообщение Anonymous »

У меня есть один фрейм данных Polars, и я пытаюсь найти различия (поля, значения которых изменились) в нескольких столбцах между группами по одному ключу. В кадре данных может быть несколько групп и более одного столбца. Группы по сути представляют собой дату и время в формате int (ГГГГММДД).
Как найти строки, в которых есть новое значение (любого) столбца в дату.
Пример данных:

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

raw_df = pl.DataFrame([
{'id': 'AAPL','update_time': 20241112,'status':'trading', 'underlying': 'y'},
{'id': 'MSFT','update_time': 20241113,'status': 'trading', 'underlying': 'x'},
{'id': 'NVDA','update_time': 20241112,'status': 'trading', 'underlying': 'z'},
{'id': 'MSFT','update_time': 20241112,'status': 'pending','underlying': 'x'},
{'id': 'AAPL','update_time': 20241113,'status': 'trading', 'underlying': 'y'},
{'id': 'NVDA','update_time': 20241113,'status': 'trading', 'underlying': 'z'},
{'id': 'TSLA','update_time': 20241112,'status': 'closed', 'underlying': 'v'},
]
)

expected_df = pl.DataFrame([
{'id': 'MSFT','update_time': 20241112,'status':'pending', 'underlying': 'x'},
{'id': 'MSFT','update_time': 20241113,'status': 'trading', 'underlying': 'x'},
]
)

Ниже показано, как выглядят вводимые данные.

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

shape: (7, 4)
┌──────┬─────────────┬─────────┬────────────┐
│ id   ┆ update_time ┆ status  ┆ underlying │
│ ---  ┆ ---         ┆ ---     ┆ ---        │
│ str  ┆ i64         ┆ str     ┆ str        │
╞══════╪═════════════╪═════════╪════════════╡
│ AAPL ┆ 20241112    ┆ trading ┆ y          │
│ MSFT ┆ 20241113    ┆ trading ┆ x          │
│ NVDA ┆ 20241112    ┆ trading ┆ z          │
│ MSFT ┆ 20241112    ┆ pending ┆ x          │
│ AAPL ┆ 20241113    ┆ trading ┆ y          │
│ NVDA ┆ 20241113    ┆ trading ┆ z          │
│ TSLA ┆ 20241112    ┆ closed  ┆ v          │
└──────┴─────────────┴─────────┴────────────┘
И ожидаемый результат ниже, показывающий идентификатор, время обновления и измененное поле. Если изменено/обновлено более одного поля, в идеале оно должно перейти в новую строку.
Я пытаюсь найти измененные поля, сгруппированные по «update_time» на ключе. 'идентификатор'. Единственное предостережение: могут быть идентификаторы, которые присутствуют в группе, но не присутствуют в другой группе, например «TSLA». Следовательно, эти идентификаторы, которые не являются общими или пересекаются между группами, можно игнорировать. Поскольку статус изменился только у MSFT, его следует отфильтровать по тем двум строкам, в которых он был обновлен. Изменения полей следует выполнять только для всех остальных столбцов, кроме update_time, который мы используем для группировки.

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

shape: (2, 3)
┌──────┬─────────────┬─────────┐
│ id   ┆ update_time ┆ status  │
│ ---  ┆ ---         ┆ ---     │
│ str  ┆ i64         ┆ str     │
╞══════╪═════════════╪═════════╡
│ MSFT ┆ 20241112    ┆ pending │
│ MSFT ┆ 20241113    ┆ trading │
└──────┴─────────────┴─────────┴
Не смог понять, как это сделать, но это самое близкое из того, что у меня есть, и оно не работает с учетом упомянутой ранее оговорки.

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

def find_updated_field_differences(df):
columns_to_check = [col for col in df.columns if col != 'id' and col != 'update_time']

sorted_df = df.sort('update_time')
grouped_df = sorted_df.groupby(["update_time"])

result_data = []

for group_key, group_df in grouped_df:
print(group_df)

for col in columns_to_check:

group_df = group_df.with_columns(
(pl.col(col) != pl.col(col).shift()).alias(f"{col}_changed")
)

differing_rows = group_df.filter(
pl.any([pl.col(f"{col}_changed") for col in columns_to_check])
)

result_data.append(differing_rows)

differing_df = pl.concat(result_data)

differing_df = differing_df.sort("id")

return differing_df
Любая помощь будет принята с благодарностью!

Подробнее здесь: https://stackoverflow.com/questions/783 ... -dataframe

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