2017-08-25 1 views
1

Sagen wir, ich habe zwei Datenrahmen, und die Spaltennamen für beide:Python Pandas wie zwei Tabellen basierend auf Teilstring zusammenführen/verbinden?

table 1 columns: 
[ShipNumber, TrackNumber, Comment, ShipDate, Quantity, Weight] 
table 2 columns: 
[ShipNumber, TrackNumber, AmountReceived] 

ich die beiden Tabellen, wenn entweder ‚ShipNumber‘ oder ‚Tracknumber‘ aus der Tabelle zusammenführen möchten 2 in ‚Kommentar‘ finden von Tabelle 1.

auch werde ich erklären, warum

merged = pd.merge(df1,df2,how='left',left_on='Comment',right_on='ShipNumber') 

in diesem Fall nicht funktioniert.

"Kommentar" -Spalte ist ein Block von Texten, die alles enthalten können, so kann ich keine genaue Übereinstimmung wie tab2.ShipNumber == tab1.Comment tun, da tab2.ShipNumber oder tab2.TrackNumber als Teilzeichenfolge in gefunden werden kann tab1.Kommentar.

Die gewünschte Ausgabetabelle sollten alle einzigartigen Spalten aus zwei Tabellen:

output table column names: 
[ShipNumber, TrackNumber, Comment, ShipDate, Quantity, Weight, AmountReceived] 

Ich hoffe, meine Frage Sinn macht ... Jede Hilfe ist wirklich, wirklich zu schätzen!

note

Das ultimative Ziel ist zwei Sätze fusionieren mit (shipnumber == shipnumber | Tracknummer == Tracknummer | shipnumber in Kommentare | Tracknummer in den Kommentaren), aber ich habe zwei Untergruppen erstellt für die ersten beiden Bedingungen, und jetzt arbeite ich an den 3. und 4. Bedingungen.

+0

Können Sie eine neue Spalte "ExtractedNum" erstellen, indem Sie einen regulären Ausdruck in der Spalte "Kommentar" verwenden, um etwas zu finden, das wie ShipNumber oder TrackNumber aussieht? Dann können Sie in der neuen ExtractedNum-Spalte zusammenführen. Oder ist es möglich, dass mehr als 1 Zahl im Kommentar steht? – nanojohn

+0

die ShipNumber und TrackNumber können nicht im selben Format bleiben .... (einige Ausnahmen existieren und wollen diese nicht ausschließen). deshalb möchte ich nur mit der Quelle übereinstimmen (Tabelle 2). und der "Kommentar" ist ein Klecks von Texten kann von allem sein. – alwaysaskingquestions

Antwort

0

Hier ist ein Beispiel basierend auf einigen erfundenen Daten. Ignoriere den ganzen Unsinn, den ich in den Datenrahmen eingefügt habe, ich habe gerade zufälliges Zeug eingegeben, um ein Beispiel-Df zum Spielen zu bekommen.

import pandas as pd 
import re 

x = pd.DataFrame({'Location': ['Chicago','Houston','Los Angeles','Boston','NYC','blah'], 
        'Comments': ['chicago is winter','la is summer','boston is winter','dallas is spring','NYC is spring','seattle foo'], 
        'Dir':  ['N','S','E','W','S','E']}) 

y = pd.DataFrame({'Location': ['Miami','Dallas'], 
        'Season': ['Spring','Fall']}) 


def findval(row): 
    comment, location, season = map(lambda x: str(x).lower(),row) 
    return location in comment or season in comment 

merged = pd.concat([x,y]) 

merged['Helper'] = merged[['Comments','Location','Season']].apply(findval,axis=1) 
print(merged) 
filtered = merged[merged['Helper'] == True] 
print(filtered) 

Anstatt Beitritt, können Sie den Datenrahmen conatenate, und dann einen Helfer erstellen, um zu sehen, wenn die Zeichenfolge einer Spalte in einer anderen gefunden wird. Sobald Sie diese Helper-Spalte haben, filtern Sie einfach die Wahren heraus.

+0

das funktioniert nicht; Tut mir leid, dass ich meine Frage nicht klargestellt habe. Ich werde meine Frage jetzt bearbeiten. – alwaysaskingquestions

+0

Grundsätzlich ist der "Kommentar" eine lange Zeichenfolge, aber shipnumber könnte eine Teilzeichenfolge sein, die in der Zeichenfolge "comment" enthalten ist. Daher kann die Zusammenführungsfunktion nicht wie folgt verwendet werden. – alwaysaskingquestions

+0

Ich bin mir nicht sicher, ob es eine Möglichkeit gibt, bei einem Funktionsaufruf mitzumachen - vielleicht die df zusammen zu verketten und dann eine Helferspalte zu machen, die eine 're.search' oder einfache' trackingnum in Kommentar oder shipnumber in comment' macht. Danach können Sie einfach das df so filtern, wie es für diese Hilfesäule normal ist. – Solaxun

0

warum so etwas wie

Count = 0 
def MergeFunction(rowElement): 
    global Count 
    df2_row = df2.iloc[[Count]] 
    if(df2_row['ShipNumber'] in rowElement['Comments'] or df2_row['TrackNumber'] 
     in rowElement['Comments'] 
    rowElement['Amount'] = df2_row['Amount'] 
    Count+=1 
    return rowElement 

df1['Amount'] = sparseArray #Fill with zeros 
new_df = df1.apply(MergeFunction) 
0

Sie könnten Index das Kommentarfeld suchen, eine Bibliothek wie Whoosh und dann eine Textsuche für jede Sendung Nummer, die Sie verwenden möchten, indem nicht tun.

Verwandte Themen