359 Stimmen

Teilen (aufteilen) Sie den Zeichenfolgeneintrag des Pandas-Datenrahmens in separate Zeilen auf

Ich habe ein Pandas DataFrame, in dem eine Spalte mit Textzeichenfolgen Komma-getrennte Werte enthält. Ich möchte jedes CSV-Feld aufteilen und für jeden Eintrag eine neue Zeile erstellen (angenommen, dass das CSV sauber ist und nur auf ',' aufgeteilt werden muss). Zum Beispiel sollte a zu b werden:

In [7]: a
Out[7]: 
    var1  var2
0  a,b,c     1
1  d,e,f     2

In [8]: b
Out[8]: 
  var1  var2
0    a     1
1    b     1
2    c     1
3    d     2
4    e     2
5    f     2

Bisher habe ich verschiedene einfache Funktionen ausprobiert, aber die Methode .apply scheint nur einen Zeilenwert als Rückgabewert zu akzeptieren, wenn sie auf einer Achse verwendet wird, und ich kann .transform nicht zum Laufen bringen. Über jede Hilfe würde ich mich freuen!

Beispieldaten:

from pandas import DataFrame
import numpy as np
a = DataFrame([{'var1': 'a,b,c', 'var2': 1},
               {'var1': 'd,e,f', 'var2': 2}])
b = DataFrame([{'var1': 'a', 'var2': 1},
               {'var1': 'b', 'var2': 1},
               {'var1': 'c', 'var2': 1},
               {'var1': 'd', 'var2': 2},
               {'var1': 'e', 'var2': 2},
               {'var1': 'f', 'var2': 2}])

Ich weiß, dass dies nicht funktioniert, weil wir durch die Verwendung von NumPy die Meta-Daten des DataFrame verlieren, aber es sollte Ihnen eine Vorstellung davon geben, was ich zu tun versucht habe:

def fun(row):
    letters = row['var1']
    letters = letters.split(',')
    out = np.array([row] * len(letters))
    out['var1'] = letters
a['idx'] = range(a.shape[0])
z = a.groupby('idx')
z.transform(fun)

3 Stimmen

Andere Lösungen auf dieser Seite funktionieren, aber ich fand die folgende kurz und effektiv. stackoverflow.com/questions/27263805/…

2 Stimmen

Für andere, die diese Seite besuchen und nach einer Lösung suchen, die mehrere Spalten beibehält, werfen Sie einen Blick auf diese Frage: stackoverflow.com/questions/17116814/…

0voto

Zhiwei Punkte 179

Ich hatte ein ähnliches Problem, meine Lösung bestand darin, das DataFrame zunächst in eine Liste von Dictionaries umzuwandeln und dann den Übergang zu vollziehen. Hier ist die Funktion:

import re
import pandas as pd

def separate_row(df, column_name):
    ls = []
    for row_dict in df.to_dict('records'):
        for word in re.split(',', row_dict[column_name]):
            row = row_dict.copy()
            row[column_name]=word
            ls.append(row)
    return pd.DataFrame(ls)

Beispiel:

>>> from pandas import DataFrame
>>> import numpy as np
>>> a = DataFrame([{'var1': 'a,b,c', 'var2': 1},
               {'var1': 'd,e,f', 'var2': 2}])
>>> a
    var1  var2
0  a,b,c     1
1  d,e,f     2
>>> separate_row(a, "var1")
  var1  var2
0    a     1
1    b     1
2    c     1
3    d     2
4    e     2
5    f     2

Sie können die Funktion auch ein wenig ändern, um die Trennung von Listenreihen zu unterstützen.

0voto

Harsha Reddy Punkte 341

Es gibt viele Antworten hier, aber es überrascht mich, dass niemand die integrierte pandas explode Funktion erwähnt hat. Schauen Sie sich den Link unten an: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html#pandas.DataFrame.explode

Aus irgendeinem Grund konnte ich nicht auf diese Funktion zugreifen, also habe ich den folgenden Code verwendet:

import pandas_explode
pandas_explode.patch()
df_zlp_people_cnt3 = df_zlp_people_cnt2.explode('people')

Bildbeschreibung eingeben

Oben ist ein Beispiel meiner Daten. Wie Sie sehen können, hatte die people Spalte Serien von Personen, und ich habe versucht, sie zu "explodieren". Der Code, den ich gegeben habe, funktioniert für Datentypen von Listen. Versuchen Sie also, Ihre durch Kommas getrennten Textdaten in Listenformat zu konvertieren. Da mein Code integrierte Funktionen verwendet, ist er viel schneller als benutzerdefinierte/apply Funktionen.

Hinweis: Möglicherweise müssen Sie pandas_explode mit pip installieren.

0voto

Kranti Punkte 36

Beim Hinzufügen einiger Details aus allen Lösungen auf dieser Seite konnte ich etwas Ähnliches wie dies erhalten (für jemanden, der es sofort verwenden muss). Die Parameter für die Funktion sind df (Eingabedatenrahmen) und key (Spalte, die einen durch ein Trennzeichen getrennten String enthält). Ersetzen Sie dies einfach durch Ihr Trennzeichen, wenn es sich von einem Semikolon ";" unterscheidet.

def split_df_rows_for_semicolon_separated_key(key, df):
    df=df.set_index(df.columns.drop(key,1).tolist())[key].str.split(';', expand=True).stack().reset_index().rename(columns={0:key}).loc[:, df.columns]
    df=df[df[key] != '']
    return df

0voto

Pavel Punkte 9

Ich habe folgende Lösung für dieses Problem gefunden:

def iter_var1(d):
    for _, row in d.iterrows():
        for v in row["var1"].split(","):
            yield (v, row["var2"])

new_a = DataFrame.from_records([i for i in iter_var1(a)],
        columns=["var1", "var2"])

0voto

Hamza usman ghani Punkte 2226

Versuchen Sie es:

vals = np.array(a.var1.str.split(",").values.tolist())    
var = np.repeat(a.var2, vals.shape[1])

out = pd.DataFrame(np.column_stack((var, vals.ravel())), columns=a.columns)
display out

      var1 var2
    0   1   a
    1   1   b
    2   1   c
    3   2   d
    4   2   e
    5   2   f

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X