2017-02-03 15 views
5

Ich habe folgende Datenrahmen:Pandas: Aggregieren von Listenwerte in Spalten

data = {'VehID' : pd.Series([10000,10000,10000,10001,10001,10001,10001]), 
     'JobNo' : pd.Series([1,2,2,1,2,3,3]), 
     'Material' : pd.Series([5005,5100,5005,5888,5222,5888,5222])} 
df = pd.DataFrame(data, columns=['VehID','JobNo','Material']) 

Es sieht wie folgt aus:

VehID JobNo Material 
0 10000  1  5005 
1 10000  2  5100 
2 10000  2  5005 
3 10001  1  5888 
4 10001  2  5222 
5 10001  3  5888 
6 10001  3  5222 

Ich möchte die Materialien identifizieren, die für jedes Fahrzeug in aufeinander folgenden Stellen auftreten . Zum Beispiel

VehID Material Jobs 
10000 5005 [1,2] 
10001 5222 [2,3] 

würde Ich mag mit for-Schleifen zu vermeiden, arbeiten. Hat jemand irgendwelche Vorschläge für eine saubere Lösung? Vielen Dank im Voraus ..

Antwort

3

Sie erste Daten auf Listen mit pandas.DataFrame.groupby und dann pandas.DataFrame.apply mit list Konstruktor als Funktion sammeln können:

>>> res = df.groupby(['VehID', 'Material'])['JobNo'].apply(list).reset_index() 
>>> res 
    VehID Material JobNo 
0 10000  5005 [1, 2] 
1 10000  5100  [2] 
2 10001  5222 [2, 3] 
3 10001  5888 [1, 3] 

Und jetzt können Sie alle nicht-konsekutiven Listen filtern:

>>> f = res.JobNo.apply(lambda x: len(x) > 1 and sorted(x) == range(min(x), max(x)+1)) 
>>> res[f] 
    VehID Material JobNo 
0 10000  5005 [1, 2] 
2 10001  5222 [2, 3] 

Sie können es wahrscheinlich mit intelligenteren Funktionen beschleunigen - zuerst speichern Sie alreadt sortierte Liste in res und überprüfen Sie dann min, max und len mit Bereich der gleichen Länge

+0

cool. Ich lerne auch Pandas, ich arbeite an Dataframe, die etwa 50K bis 80K Einträge haben. Oben ist hilfreich für mich. Schätze 'sortierte (x) == Bereich (min (x), max (x) +1)' Logik, um aufeinanderfolgende Jobs zu prüfen –

+0

Danke! Was ist, wenn mein Datenrahmen jetzt wie unten gezeigt ist. – javelina

Verwandte Themen