Ich möchte eine Zeichenfolgenserie unter aufteilen unterschiedliche Punkte je nach Länge bestimmter Teilzeichenfolgen:

In [47]: df = pd.DataFrame(['group9class1', 'group10class2', 'group11class20'], columns=['group_class'])
In [48]: split_locations = df.group_class.str.rfind('class')
In [49]: split_locations
Out[49]: 
0    6
1    7
2    7
dtype: int64
In [50]: df
Out[50]: 
      group_class
0    group9class1
1   group10class2
2  group11class20

Meine Ausgabe sollte folgendermaßen aussehen:

      group_class    group    class
0    group9class1   group9   class1
1   group10class2  group10   class2
2  group11class20  group11  class20

Ich dachte halb, das könnte funktionieren:

In [56]: df.group_class.str[:split_locations]
Out[56]: 
0   NaN
1   NaN
2   NaN

Wie kann ich meine Zeichenfolgen anhand der variablen Positionen in split_locations aufteilen?

5
LondonRob 7 Aug. 2015 im 18:14

3 Antworten

Beste Antwort

Dies funktioniert, indem Sie mit double [[]] auf den Indexwert des aktuellen Elements zugreifen, um in die split_locations -Serie zu indizieren:

In [119]:    
df[['group_class']].apply(lambda x: pd.Series([x.str[split_locations[x.name]:][0], x.str[:split_locations[x.name]][0]]), axis=1)
Out[119]:
         0        1
0   class1   group9
1   class2  group10
2  class20  group11

Oder wie @ajcr vorgeschlagen hat, können Sie extract:

In [106]:

df['group_class'].str.extract(r'(?P<group>group[0-9]+)(?P<class>class[0-9]+)')
Out[106]:
     group    class
0   group9   class1
1  group10   class2
2  group11  class20

BEARBEITEN

Regex Erklärung:

Der Regex stammt von @ajcr (danke!) und verwendet str.extract Um Gruppen zu extrahieren, werden die Gruppen zu neuen Spalten.

Also ?P<group> Hier wird eine ID für eine bestimmte Gruppe angegeben, nach der gesucht werden soll. Wenn diese fehlt, wird ein int für den Spaltennamen zurückgegeben.

Der Rest sollte daher selbsterklärend sein: group[0-9] sucht nach der Zeichenfolge group, gefolgt von den Ziffern im Bereich [0-9], was die [] angeben. Dies entspricht { {X4}} wobei \d eine Ziffer bedeutet.

Es könnte also wie folgt umgeschrieben werden:

df['group_class'].str.extract(r'(?P<group>group\d+)(?P<class>class\d+)')
3
Community 23 Mai 2017 im 12:22

Sie können zip auch zusammen mit einem Listenverständnis verwenden.

df['group'], df['class'] = zip(
    *[(string[:n], string[n:]) 
      for string, n in zip(df.group_class, split_locations)])

>>> df
      group_class    group    class
0    group9class1   group9   class1
1   group10class2  group10   class2
2  group11class20  group11  class20
2
Alexander 14 Juni 2018 im 00:40

Verwenden Sie einen regulären Ausdruck, um die Zeichenfolge zu teilen

 import re

 regex = re.compile("(class)")
 str="group1class23"
 # this will split the group and the class string by adding a space between them, and using a simple split on space.
 split_string = re.sub(regex, " \\1", str).split(" ")

Dies gibt das Array zurück:

 ['group9', 'class23']

Um zwei neue Spalten an Ihr DataFrame anzuhängen, haben Sie folgende Möglichkeiten:

new_cols = [re.sub(regex, " \\1", x).split(" ") for x in df.group_class]
df['group'], df['class'] = zip(*new_cols)

Was in ... endet:

      group_class    group    class
0    group9class1   group9   class1
1   group10class2  group10   class2
2  group11class20  group11  class20
2
LondonRob 7 Aug. 2015 im 15:40