Seite 1 von 1

Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 11:45
von H3llo
Hallo,

ich habe eine Textdatei, in der mehrere Zeilen mit Daten sind. Der erste Eintrag einer Zeile beginnt immer mit "P1", "S1", "C1", "CA" oder "BC". Ich möchte dieses DataFrame nun in mehrere DataFrames aufteilen. Die Aufteilung soll entsprechend der eben geschilderten Zeilenanfänge erfolgen. Außerdem soll jedes DataFrame in Spalte 0 eine ID bekommen. Diese ID soll der Anzahl der Zeilen, die mit "P1" anfangen und oberhalb der aktuellen Zeile stehen, entsprechen. Ein Beispiel:

Die ersten Einträge der Textdatei sehen wie folgt aus:

P1ABC
S1EEF
S1DDF
C1AAA
CADDF
BCOIU
P1HDF
S1EEF
S1UUU
S1ZTZ
C1AAA
CADDF
C1AAB
BCOIV

Die neuen DataFrames sollen dann wie folgt aussehen:

1 P1ABC
2 P1HDF

1 S1EEF
1 S1DDF
2 S1EEF
2 S1UUU
2 S1ZTZ

1 C1AAA
2 C1AAA
2 C1AAB

1 CADDF
2 CADDF

1 BCOIU
2 BCOIV

Wie bekomme ich das so hin? (Wenn möglich ohne Schleife!)

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 12:08
von __blackjack__
@H3llo: Du suchst die `groupby()`-Methode und die Methoden hinter `Series.str`. Die Beschreibung für die neue Spalte habe ich nicht verstanden.

Code: Alles auswählen

In [41]: df
Out[41]: 
        0
0   P1ABC
1   S1EEF
2   S1DDF
3   C1AAA
4   CADDF
5   BCOIU
6   P1HDF
7   S1EEF
8   S1UUU
9   S1ZTZ
10  C1AAA
11  CADDF
12  C1AAB
13  BCOIV

In [42]: list(df.groupby(df[0].str.slice(0, 2)))
Out[42]: 
[('BC',
          0
  5   BCOIU
  13  BCOIV),
 ('C1',
          0
  3   C1AAA
  10  C1AAA
  12  C1AAB),
 ('CA',
          0
  4   CADDF
  11  CADDF),
 ('P1',
         0
  0  P1ABC
  6  P1HDF),
 ('S1',
         0
  1  S1EEF
  2  S1DDF
  7  S1EEF
  8  S1UUU
  9  S1ZTZ)]

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 12:26
von H3llo
Also nochmal zu den IDs. Letztendlich sollen die so aussehen:

1 P1ABC
1 S1EEF
1 S1DDF
1 C1AAA
1 CADDF
1 BCOIU
2 P1HDF
2 S1EEF
2 S1UUU
2 S1ZTZ
2 C1AAA
2 CADDF
2 C1AAB
2 BCOIV

Die ID soll also dann eins hoch gezählt werden, wenn die Zeile mit "P1" beginnt. Und das ganze ohne Schleife.

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 12:30
von Sirius3
Du suchst also eine Kombination aus str.startswith und cumsum.

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 13:13
von H3llo
Keine Ahnung :) Könntest du etwas genauer ausführen, wie eine Lösung damit aussehen könnte?

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 13:30
von __blackjack__
@H3llo: Man könnte eine neue Spalte mit 0en einführen, da überall wo etwas in der Textspalte mit "P1" anfängt eine 1 setzen, und dann mit `cumsum()` über die Spalte laufen.

Edit: Geht sogar etwas einfacher, weil `True` und `False` ja im Grunde auch die Zahlen 1 und 0 sind, kann man `cumsum()` gleich auf das Ergebnis von dem Test ob die Werte mit "P1" anfangen, anwenden und das dann als weitere Spalte setzen:

Code: Alles auswählen

In [10]: df                                                                     
Out[10]: 
        0
0   P1ABC
1   S1EEF
2   S1DDF
3   C1AAA
4   CADDF
5   BCOIU
6   P1HDF
7   S1EEF
8   S1UUU
9   S1ZTZ
10  C1AAA
11  CADDF
12  C1AAB
13  BCOIV

In [11]: df[0].str.startswith("P1")                                             
Out[11]: 
0      True
1     False
2     False
3     False
4     False
5     False
6      True
7     False
8     False
9     False
10    False
11    False
12    False
13    False
Name: 0, dtype: bool

In [12]: df[0].str.startswith("P1").cumsum()                                    
Out[12]: 
0     1
1     1
2     1
3     1
4     1
5     1
6     2
7     2
8     2
9     2
10    2
11    2
12    2
13    2
Name: 0, dtype: int64

In [13]: df[1] = df[0].str.startswith("P1").cumsum()                            

In [14]: df                                                                     
Out[14]: 
        0  1
0   P1ABC  1
1   S1EEF  1
2   S1DDF  1
3   C1AAA  1
4   CADDF  1
5   BCOIU  1
6   P1HDF  2
7   S1EEF  2
8   S1UUU  2
9   S1ZTZ  2
10  C1AAA  2
11  CADDF  2
12  C1AAB  2
13  BCOIV  2
Man sollte als Spaltenindex aber besser sinnvolle Namen für die Spalten verwenden statt nichtssagender Nummern. Das Problem was das löst wird deutlich wenn man sich klar macht, das *ich* das nicht machen kann, weil ich keine Ahnung habe was das bedeuten soll, eben weil die Spalten keine vernünftigen Bezeichnungen haben, sondern nichtssagende Nummern.

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 13:37
von H3llo
Mit welcher Funktion könnte man die 1 in den Zeilen mit "P1" setzen?

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 13:42
von __blackjack__
@H3llo: Ich hatte da noch eine einfachere Möglichkeit ergänzt. Ansonsten solltest Du mal das/die Tutorials aus der Pandas-Dokumentation durcharbeiten. Aus was so ein `DataFrame` besteht, wie man Spalten und Zeilen selektieren kann, und auch wie man ausgewählten Zellen in einer Spalte neue Werte zuweisen kann, und so weiter.

Re: Pandas DataFrame in mehrere DataFrames aufteilen mit ID

Verfasst: Donnerstag 1. September 2022, 13:58
von H3llo
@blackjack: Hatte schon geantwortet, als du deinen Edit veröffentlicht hast.

Vielen Dank! Das ist genau das, was ich gesucht habe. Tolle Lösung!