Ich versuche, basierend auf ihrer Sequenzbeziehung zwischen den beiden Spalten zu gruppieren.
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
Ich erwarte das Ergebnis etwas unten:
Um es klarer zu machen: - df1 und df2 haben eine Beziehung, die auf ihrer Reihenfolge basiert. Zum Beispiel hat 10 eine direkte Beziehung zu 20 und 10 hat eine indirekte Beziehung zu 30 bis 20. Und 10 hat eine indirekte Beziehung zu 40 bis 20 und 30. Ein weiteres Beispiel, nehmen wir, 80 hat eine direkte Beziehung zu 70 und indirekte Beziehung zu 100 bis 70. Dies funktioniert für den Rest der Spaltenwerte.
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
Ich versuche, das folgende Skript zu verwenden, aber es konnte mir nicht gelingen.
(df.groupby('df1')
.agg({ 'df2' : ','.join})
.reset_index()
.reindex(columns=df.columns))
Könnte jemand bei dieser Herausforderung helfen? Wenn es hier bei Stack overflow eine ähnliche Lösung gibt, lassen Sie es mich bitte wissen.
Bearbeiten: Die erste Antwort funktioniert perfekt mit dem obigen Beispiel, aber wenn ich es mit den Daten versuche, die ich machen möchte, funktioniert es nicht richtig. Meine realen Daten sehen wie folgt aus.
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 -
Antworten:
Eine mögliche Lösung:
Drucke:
EDIT: Andere Lösung basierend auf neuen Eingabedaten. Jetzt suche ich nach möglichen Kreisen im Pfad:
Drucke:
Oder
pprint(d, width=250)
:EDIT 2: If
df
ist Ihr Eingabedatenrahmen mit den Spalten "df1" und "df2":quelle
d[k].extend(chain.from_iterable(d.get(v, []) for v in d[k]))
das funktioniert? Ich sah den Arzt an, konnte ihm aber nicht folgen.chain.from_iterable
, um die Iterable zu reduzieren - in diesem Fall besteht die Iterable aus Listen aus dem Wörterbuchd
(oder leeren Listen, wenn der Schlüsselv
ind
- nicht vorhanden istd.get(v, [])
). Dann benutze ich diese Werte, um die Liste zu erweitern, unter der gespeichert istd[k]
.if not (line := line.strip().split()):
ist zu sagenif not (line != line.strip().split()):
? oder etwas anderes. Ich bekomme Fehler mit:
. Wenn ich es schaffe,!=
bekomme ich einenIndexError: string index out of range
Fehler in der Leitungdf1.append(int(line[1]))
.Hallo danke für die Klarstellung, ich habe eine Lösung mit einer rekursiven Funktion, die Sie ausprobieren können. Möglicherweise nicht effizient für große Datenrahmen, scheint aber gut zu funktionieren. Die Funktion gibt eine Liste zurück, aber Sie können die resultierende Serie bearbeiten, um die Liste zu einer Zeichenfolge zusammenzufügen, wie Sie möchten.
quelle
Dies sollte den Trick tun:
Ausgabe:
(*) Ich habe auch mit erweitertem Datenrahmen nachgesehen - es ist ziemlich schnell, ich werde die Ausgabe nicht freigeben, da meine IDE sie abschneidet;)
quelle
node
(einer Ihrer Parameter in der Funktion)? Könntest du es mir sagen?node
ist der Wert, auf dem Sie sich gerade befinden. Sie geben es also zurück, und falls es andere Eltern als sich selbst hat (sog. Zirkelverweis), iterieren Sie über die Eltern und führen dieselbe Funktion für sie aus.<generator object recursive_walk at 0x0000022A67551D48>
. Welches ist ich weiß nicht, was es bedeutet.list(recursive_walk(...))
oder[el for el in recursive_walk(...)]
Funktion gibt zurückgenerator
- was im Wesentlichen bedeutet - nicht alle Elemente gleichzeitig, wie z. B.list
oder,tuple
aber iterierbar, mit denen Sie alle Werte einzeln zurückgeben können.