2016-11-22 7 views
1

Ich habe eine Datenmenge, die ein wenig wie folgt aussieht:Python Pandas - Zeilen zusammenführen, wenn einige Werte sind leer

ID Name   Address  Zip Cost 
1 Bob the Builder 123 Main St 12345 
1 Bob the Builder      $99,999.99 
2 Bob the Builder 123 Sub St 54321 $74,483.01 
3 Nigerian Prince Area 51  33333 $999,999.99 
3 Pinhead Larry Las Vegas 31333 $11.00 
4 Fox Mulder  Area 51    $0.99 

wo fehlende Daten in Ordnung ist, es sei denn, es ist offensichtlich, dass sie zusammengefügt werden können. Was ich damit meine, ist, dass anstelle des obigen Datasets die Zeilen zusammengeführt werden sollen, bei denen ID und Name identisch sind und die anderen Features die Leerzeichen des anderen ausfüllen können. Zum Beispiel würde der Datensatz oben geworden:

ID Name   Address  Zip Cost 
1 Bob the Builder 123 Main St 12345 $99,999.99 
2 Bob the Builder 123 Sub St 54321 $74,483.01 
3 Nigerian Prince Area 51  33333 $999,999.99 
3 Pinhead Larry Las Vegas 31333 $11.00 
4 Fox Mulder  Area 51    $0.99 

Ich habe darüber nachgedacht, df.groupby(["ID", "Name"]) verwenden und dann die Saiten verketten, da die fehlenden Werte leere Strings sind, bekam aber kein Glück mit ihm.

Die Daten wurden von Websites gekratzt, also mussten sie eine Menge Reinigung durchmachen, um hier zu enden. Ich kann mir keine elegante Art vorstellen, das herauszufinden!

Antwort

0

Ich werde einen Algorithmus beschreiben:

  1. alle Zeilen Auf die Seite legen, in der alle Felder ausgefüllt werden. Wir müssen diese nicht anfassen.
  2. Erstellen Sie ein boolesches DataFrame wie die Eingabe, wobei leere Felder False sind und ausgefüllte Felder True sind. Dies ist df.notnull().
  3. Für jeden Namen in df.Name.unique():
    1. df[df.Name == name] als Workingset Nehmen.
    2. Summe jedes Paares (oder Tupels) von booleschen Zeilen, was dazu führt, dass ein boolescher Vektor die gleiche Breite wie die Eingabespalten hat, mit Ausnahme derer, die immer gefüllt sind. Im Beispiel bedeutet dies [True, True, False] und [False, False, True], also ist die Summe [1, 1, 1].
    3. Wenn die Summe überall gleich 1 ist, kann dieses Paar (oder Tupel) von Zeilen zusammengeführt werden.

Aber es gibt eine Tonne von möglichen Grenzfällen hier, wie was zu tun ist, wenn Sie drei Reihen A, B haben, C und Sie könnten entweder A + B oder A + C verschmelzen. Es wird hilfreich sein, wenn Sie die in den Daten vorhandenen Einschränkungen eingrenzen können, bevor Sie den Merging-Algorithmus implementieren.

+0

Vielen Dank! Ich habe dieses Muster auch bemerkt, als ich eine Groupby() auf dem Datenrahmen gemacht habe, aber nicht wirklich wusste, was ich damit machen sollte. Und ich hätte über die Einschränkungen geklärt werden sollen - die Randfälle waren schon erledigt, also waren es nur Sätze von 2 Reihen mit Duplikaten wie diesem. – kug3lblitz

1

Dies funktioniert nur, wenn Zeilen, die wir potenziell zusammenführen, nebeneinander sind.

Setup

df = pd.DataFrame(dict(
     ID=[1, 1, 2, 3, 3, 4], 
     Name=['Bob the Builder'] * 3 + ['Nigerian Prince', 'Pinhead Larry', 'Fox Mulder'], 
     Address=['123 Main St', '', '123 Sub St', 'Area 51', 'Las Vegas', 'Area 51'], 
     Zip=['12345', '', '54321', '33333', '31333', ''], 
     Cost=['', '$99,999.99', '$74,483.01', '$999.999.99', '$11.00', '$0.99'] 
    ))[['ID', 'Name', 'Address', 'Zip', 'Cost']] 

füllen fehlende
replace('', np.nan) dann füllen vorwärts dann füllen zurück

df_ = df.replace('', np.nan).ffill().bfill() 

conca t
nehmen letzte Reihe gefüllt df_ Wenn es eine doppelte Zeile
nicht df gefüllt nehmen, wenn nicht

dupliziert
pd.concat([ 
     df_[df_.duplicated()], 
     df.loc[df_.drop_duplicates(keep=False).index] 
    ]) 

enter image description here

Verwandte Themen