Basicamente, quero agrupar todos os registros que correspondem a qualquer uma das chaves
Entrada:
|id|key1|key2|
|-|-|-|
|1|a|x|
|2|a|y|
|3|b|y|
|4|c|z|
Saída desejada: (As 3 primeiras linhas são agrupadas)
|key1 (or any identifier, I only care about the final counts)|len|
|-|-|
|a|3|
|c|1|
Minha tentativa de solução (incompleta):
import polars as pl
df = pl.DataFrame({
'id': [1, 2, 3, 4],
'key1': ['a', 'a', 'b', 'c'],
'key2': ['x', 'y', 'y', 'z'],
})
df = (
df.group_by(
'key1',
'key2',
)
.len()
.group_by('key1')
.agg(
pl.col('key2'),
pl.col('len').sum()
)
)
print(df)
O que dá:
|key1|key2|len|
|-|-|-|
|a|["y", "x"]|2|
|b|["y"]|1|
|c|["z"]|1|
No entanto, não tenho certeza de como agruparia isso ainda mais por key2 (mesclando as linhas a e b, já que elas têm um valor comum de y) preservando a soma de len
Se entendi corretamente, você quer criar relações de equivalência entre
key1
ekey2
e continuar mesclando coisas em grupos se houver uma cadeia de relacionamentos que conecte os dois? Então, neste caso, como há uma linha,a, y
quaisquer linhas que contenhama
ouy
devem ser mescladas?Neste caso é difícil expressar isso diretamente em Polars, mas você pode fazer um híbrido com
scipy
'sDisjointSet
.Primeiro, reúna todas as chaves e relacionamentos exclusivos:
Em seguida, insira-os em um
DisjointSet
e mescle-os em grupos:Em seguida, converta isso
DisjointSet
em umaDataFrame
chave de mapeamento para agrupar o índice:Por fim, juntamos o
group_idx
ao nosso dataframe original e agrupamos pelo índice do grupo:Dando assim a nossa saída: