Estou tentando agrupar com base no relacionamento de sequência entre as duas colunas.
d = {'df1':[10,20, 30, 60, 70, 40, 30, 70], 'df2':[20, 30, 40, 80, 70, 50, 90, 100]}
df = pd.DataFrame(data = d)
df
df1 df2
0 10 20
1 20 30
2 30 40
3 60 80
4 80 70
5 40 50
6 30 90
7 70 100
Eu estou esperando o resultado algo abaixo:
Para deixar mais claro: - df1 e df2 têm um relacionamento com base em sua sequência. Por exemplo, 10 tem uma relação direta com 20 e 10 tem uma relação indireta com 30 a 20. E também 10 tem uma relação indireta com 40 a 20 e 30. Um exemplo adicional, vamos considerar 80, tem uma relação direta com 70 e relação indireta de 100 a 70. Isso funciona para o restante dos valores da coluna.
df1 | df2
-----|-------------------
0 10 | 20, 30, 40, 50, 90
1 20 | 30, 40, 50, 90
2 30 | 40, 50, 90
3 60 | 80, 70, 100
4 80 | 70, 100
5 40 | 50
6 70 | 100
Estou tentando usar o script abaixo, mas não consegui.
(df.groupby('df1')
.agg({ 'df2' : ','.join})
.reset_index()
.reindex(columns=df.columns))
Alguém poderia ajudar nesse desafio? Se houver alguma solução semelhante aqui no Stack overflow, por favor me avise.
Edit: A primeira resposta funciona perfeitamente com o exemplo acima, mas quando tento com os dados que desejo fazer, não funciona corretamente. meus dados reais se parecem abaixo.
df1 df2
0 10 20
1 10 30
2 10 80
3 10 90
4 10 120
5 10 140
6 10 170
7 20 180
8 30 40
9 30 165
10 30 175
11 40 20
12 40 50
13 50 60
14 60 70
15 70 180
16 80 180
17 90 100
18 100 110
19 110 180
20 120 130
21 130 180
22 140 150
23 150 160
24 160 165
25 165 180
26 165 200
27 170 175
28 175 180
29 175 200
30 180 190
31 190 200
32 200 210
33 210 220
34 220 230
35 230 240
36 240 -
Respostas:
Uma solução possível:
Impressões:
EDIT: Outra solução baseada em novos dados de entrada. Agora estou verificando possíveis círculos no caminho:
Impressões:
Ou
pprint(d, width=250)
:EDIT 2: Se
df
é o seu quadro de dados de entrada com as colunas "df1" e "df2":fonte
d[k].extend(chain.from_iterable(d.get(v, []) for v in d[k]))
isso funciona? Olhei para o médico, mas não consegui segui-lo.chain.from_iterable
para achatar o iterável - nesse caso, o iterável consiste em listas do dicionáriod
(ou listas vazias, se a chavev
não existir emd
-d.get(v, [])
). Então eu uso esses valores para estender a lista armazenada emd[k]
.if not (line := line.strip().split()):
é para dizerif not (line != line.strip().split()):
? ou alguma outra coisa. Estou recebendo erro com:
. Quando eu faço isso!=
, estou recebendoIndexError: string index out of range
erro na linhadf1.append(int(line[1]))
.Oi obrigado pelo esclarecimento, eu tenho uma solução com uma função recursiva que você pode tentar. Pode não ser eficiente para grandes quadros de dados, mas parece funcionar bem. A função retorna uma lista, mas você pode editar a série resultante para ingressar na lista em uma sequência da maneira que desejar.
fonte
Isso deve fazer o truque:
Resultado:
(*) Eu também verifiquei com o dataframe estendido - é muito rápido, não compartilharei a saída, pois meu IDE está truncando;)
fonte
node
(um dos seus parâmetros na função)? Você poderia me dizer?node
é o valor em que você está atualmente. Então, você o devolve e, caso tenha pais, diferente de si mesmo (chamada referência circular), você itera sobre os pais e executa a mesma função para eles.<generator object recursive_walk at 0x0000022A67551D48>
. O que é que eu não sei o que isso significa.list(recursive_walk(...))
ou[el for el in recursive_walk(...)]
função retornagenerator
- o que significa essencialmente - nem todos os elementos de uma vez, como por exemplo,list
ou,tuple
mas fornece iterável que você pode usar para retornar todos os valores um por um.