2016-03-29 36 views
2

Ich habe eine CSV-Datei, die etwa wie folgt aussieht:Merging eine unbestimmte Anzahl von Zeilen in einem Datenrahmen

tid || instr_count || fnname 
============================= 
22 ||  892806 || main 
22 ||   18 || randlc 
22 ||   120 || makea 

Ich mag die Werte von instr_count zusammen basierend fusionieren, ob oder nicht fnname in a erscheint gegebene Liste. Wenn zum Beispiel meine Liste ['main', 'makea'] ist, sollte die endgültige Tabelle wie folgt aussehen:

tid || instr_count || fnname 
============================= 
22 ||  892806 || main 
22 ||   138 || makea 

Ich weiß nicht, vor der Zeit, wie viele Einträge zwischen zwei Werten in der angegebenen Liste sein wird - so kann es sein, ähnlich dieser:

tid || instr_count || fnname 
============================= 
22 ||  892806 || main 
22 ||   18 || randlc 
22 ||   7 || randlc 
22 ||   35 || randlc 
22 ||   20 || randlc 
22 ||   120 || makea 

, die an zusammengepresst werden sollten:

tid || instr_count || fnname 
============================= 
22 ||  892806 || main 
22 ||   200 || makea 

habe ich diese Werte in einem Dataframe mit Pandas 0.17.1 und python 2.7.6 geladen. Hier ist, was ich bisher:

def compressDataframes(df): 

    new_df = pd.DataFrame(columns=df.columns) 
    instr_count = 0 
    i = 0 
    for row in df.itertuples(): 
     instr_count += row[2] 
     if any(f in row[3] for f in FUNCS): #FUNCS is my "given list" 
      new_df.loc[i] = [row[1], instr_count, row[3]] 
      i += 1 
      instr_count = 0 

    return new_df 

Dies funktioniert, aber ich vermute, dass es einen Weg geben muss, es zu tun schneller (ich mit einigen sehr großen (> 10 GB) Datensätze gerade arbeite). Hat jemand irgendwelche Vorschläge?

Antwort

1

Ich glaube, Sie isin mit boolean indexing für die Schaffung neuer Spalte grouped verwenden können, die erste enthält NaN wo keine Daten sind, und dann durch fillna gültige Beobachtung gefüllt Lücke (Backfill) zu füllen. Zuletzt mit groupby Aggregat sum der Spalte instr_count:

li = ['main','makea'] 

df['grouped'] = df.loc[df['fnname'].isin(li), 'fnname'] 

df['grouped'] = df['grouped'].fillna(method='bfill') 

print df 
    tid instr_count fnname grouped 
0 22  892806 main main 
1 22   18 randlc makea 
2 22   120 makea makea 

print df.groupby(['tid','grouped'])['instr_count'].sum().reset_index() 
    tid grouped instr_count 
0 22 main  892806 
1 22 makea   138 

Oder mit agg:

print df.groupby('grouped').agg({'tid':'first', 'instr_count': sum}).reset_index() 

    grouped tid instr_count 
0 main 22  892806 
1 makea 22   138 

Zweite Probe:

li = ['main','makea'] 
df['grouped'] = df.loc[df['fnname'].isin(li), 'fnname'] 
df['grouped'] = df['grouped'].fillna(method='bfill') 

print df 
    tid instr_count fnname grouped 
0 22  892806 main main 
1 22   18 randlc makea 
2 22   7 randlc makea 
3 22   35 randlc makea 
4 22   20 randlc makea 
5 22   120 makea makea 

print df.groupby(['tid','grouped'])['instr_count'].sum().reset_index() 
    grouped tid instr_count 
0 main 22  892806 
1 makea 22   200 

print df.groupby('grouped').agg({'tid':'first', 'instr_count': sum}).reset_index() 
    tid grouped instr_count 
0 22 main  892806 
1 22 makea   200 
+0

realisiert Just - ich glaube nicht, das richtig funktioniert, wenn ich habe so etwas wie 'main, randlc, randlc, makea, makea'. Der erste 'makea' wird in den zweiten gruppiert, oder? – tonysdg

+0

Ja, Sie haben Recht. – jezrael

+0

Wäre es möglich, die Zeilennummer in die gruppierte Spalte zu kopieren? Das würde eine eindeutige Kennung ergeben, die dann wieder gefüllt werden könnte. – tonysdg

Verwandte Themen