Verketten Sie Strings aus mehreren Zeilen mit Pandas groupby

Lesezeit: 5 Minuten

Benutzeravatar von mattiasostmar
Mattiasostmar

Ich möchte mehrere Zeichenfolgen in einem Datenrahmen basierend auf einem Groupedby in Pandas zusammenführen.

Das ist mein Code bisher:

import pandas as pd
from io import StringIO

data = StringIO("""
"name1","hej","2014-11-01"
"name1","du","2014-11-02"
"name1","aj","2014-12-01"
"name1","oj","2014-12-02"
"name2","fin","2014-11-01"
"name2","katt","2014-11-02"
"name2","mycket","2014-12-01"
"name2","lite","2014-12-01"
""")

# load string as stream into dataframe
df = pd.read_csv(data,header=0, names=["name","text","date"],parse_dates=[2])

# add column with month
df["month"] = df["date"].apply(lambda x: x.month)

Ich möchte, dass das Endergebnis so aussieht:

Geben Sie hier die Bildbeschreibung ein

Ich verstehe nicht, wie ich Groupby verwenden und eine Art Verkettung der Zeichenfolgen in der Spalte “Text” anwenden kann. Jede Hilfe geschätzt!

Benutzeravatar von EdChum
EdChum

Sie können nach gruppieren 'name' Und 'month' Spalten, dann anrufen transform die Daten zurückgibt, die an der ursprünglichen df ausgerichtet sind, und ein Lambda anwendet, wo we join die Texteinträge:

In [119]:

df['text'] = df[['name','text','month']].groupby(['name','month'])['text'].transform(lambda x: ','.join(x))
df[['name','text','month']].drop_duplicates()
Out[119]:
    name         text  month
0  name1       hej,du     11
2  name1        aj,oj     12
4  name2     fin,katt     11
6  name2  mycket,lite     12

Ich unterfüge die ursprüngliche DF, indem ich eine Liste der interessierenden Spalten übergebe df[['name','text','month']] hier und dann anrufen drop_duplicates

BEARBEITEN Eigentlich kann ich nur anrufen apply und dann reset_index:

In [124]:

df.groupby(['name','month'])['text'].apply(lambda x: ','.join(x)).reset_index()

Out[124]:
    name  month         text
0  name1     11       hej,du
1  name1     12        aj,oj
2  name2     11     fin,katt
3  name2     12  mycket,lite

aktualisieren

Die lambda ist hier unnötig:

In[38]:
df.groupby(['name','month'])['text'].apply(','.join).reset_index()

Out[38]: 
    name  month         text
0  name1     11           du
1  name1     12        aj,oj
2  name2     11     fin,katt
3  name2     12  mycket,lite

  • In pandas < 1.0, .drop_duplicates() ignoriert den Index, was zu unerwarteten Ergebnissen führen kann. Sie können dies vermeiden, indem Sie verwenden .agg(lambda x: ','.join(x)) anstatt .transform().drop_duplicates().

    – Matthias Fripp

    30. Mai 2020 um 2:41 Uhr

  • Ordentlich und unkompliziert. Eminent fleixible auch

    – Raghavan vmvs

    8. September 2020 um 8:53 Uhr

  • drop_duplicates() funktioniert möglicherweise nicht, wenn Sie keinen Parameter einschließen drop_duplicates(inplace=True) oder schreiben Sie einfach die Codezeile um als df = df[['name','text','month']].drop_duplicates()

    – IAmBotmaker

    23. September 2020 um 11:46 Uhr


  • Was stellt sicher, dass der Text zB in der ersten Spalte tatsächlich „hej du“ lautet und nicht „du hej“? Gibt es irgendwo eine implizite Sortierung? Wie kann ich dies explizit machen, zB nach der Datumsspalte sortieren?

    – Thomas

    4. August 2021 um 13:55 Uhr

  • Warum wurde „hej,du“ im Abschnitt „Aktualisieren“ zu „du“ geändert?

    – ständiger Fremder

    19. März 2022 um 23:11 Uhr

Benutzeravatar von Ram Prajapati
Ram Prajapati

Wir können gruppiere nach die Spalten „Name“ und „Monat“, Dann ruf an agg() Funktionen der DataFrame-Objekte von Panda.

Die Aggregationsfunktion, die von der bereitgestellt wird agg() Funktion ermöglicht die Berechnung mehrerer Statistiken pro Gruppe in einer Berechnung.

df.groupby(['name', 'month'], as_index = False).agg({'text': ' '.join})

Geben Sie hier die Bildbeschreibung ein

  • Hallo, irgendwelche Ideen zum Löschen von Duplikaten mit der agg-Funktion?

    – kağan hazal koçdemir

    14. September 2021 um 19:40 Uhr

  • @kağanhazalkoçdemir agg({'text': lambda x: ' '.join(set(x))})

    – Nicolas78

    28. September 2021 um 8:16 Uhr


  • Wie kann man diese Methode in einem Fall verwenden, in dem NULLen in der Spalte ‘text’ erlaubt sind?

    – Andew

    21. Juli 2022 um 16:42 Uhr

  • f = lambda x: func(x, *args, **kwargs) TypeError: sequence item 45: expected str instance, NoneType found auf NULL- oder None-Werten in der Datenbank

    – Andew

    21. Juli 2022 um 16:43 Uhr

  • Dadurch können Sie auch zusätzliche Spalten behalten, beispielsweise durch Hinzufügen , 'othercol': 'last' in die agg Diktat

    – fantastisch

    13. September 2022 um 5:53 Uhr

Benutzeravatar von Rutger Hofste
Rütger Höfste

Die Antwort von EdChum bietet Ihnen viel Flexibilität, aber wenn Sie nur Zeichenfolgen in einer Spalte von Listenobjekten verketten möchten, können Sie auch:

output_series = df.groupby(['name','month'])['text'].apply(list)

  • Mann, du hast mir gerade viel Zeit gespart. Danke schön. Dies ist der beste Weg, die mir bekannten chronologischen Listen von Registrierungen/Benutzer-IDs in „Kohorten“ zusammenzustellen. Vielen Dank noch mal.

    – Alex Fedotow

    28. Juni 2020 um 2:37 Uhr

  • Diese Lösung hat für mich sehr gut funktioniert, um auch die einzigartigen Erscheinungen zu erhalten. Ich habe einfach „set“ anstelle von „list“ verwendet und dann einen Join und Presto verkettet. Beachten Sie, dass es nicht funktioniert, wenn nan-Werte vorhanden sind, also musste ich zuerst fillna() für das Textfeld verwenden. In meinem Fall endete der Befehl: df.groupby([‘doc_id’])[‘author’].apply(set).apply(“, “.join).reset_index()

    – warum geht das nicht

    11. April 2022 um 12:52 Uhr


  • Ich glaube nicht, dass dies Leerzeichen zwischen den Zeichenfolgen hinzufügt, oder?

    – Rechnung

    12. April 2022 um 15:44 Uhr

Benutzeravatar von Ismail
Ismail

Wenn Sie Ihren “Text” in einer Liste verketten möchten:

df.groupby(['name', 'month'], as_index = False).agg({'text': list})

Benutzeravatar von Nic Scozzaro
Nic Scozzaro

Für mich waren die oben genannten Lösungen nah, fügten aber einige unerwünschte hinzu /n's Und dtype:objectalso hier ist eine modifizierte Version:

df.groupby(['name', 'month'])['text'].apply(lambda text: ''.join(text.to_string(index=False))).str.replace('(\\n)', '').reset_index()

Benutzeravatar von Ashish Anand
Ashish Anand

Bitte versuchen Sie diese Codezeile: –

df.groupby(['name','month'])['text'].apply(','.join).reset_index()

Benutzeravatar von MMSA
MMSA

Allerdings ist dies eine alte Frage. Aber nur für den Fall. Ich habe den folgenden Code verwendet und es scheint wie ein Zauber zu funktionieren.

text="".join(df[df['date'].dt.month==8]['text'])

1443260cookie-checkVerketten Sie Strings aus mehreren Zeilen mit Pandas groupby

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy