2013-06-09 14 views
9

Alcuni dei miei dati assomiglia:Python Pandas - fusione file duplicati per lo più

date, name, value1, value2, value3, value4 
1/1/2001,ABC,1,1,, 
1/1/2001,ABC,,,2, 
1/1/2001,ABC,,,,35 

sto cercando di arrivare al punto in cui posso correre

data.set_index(['date', 'name']) 

Ma, con i dati come -è, naturalmente ci sono duplicati (come mostrato in precedenza), quindi non posso farlo (e non voglio un indice con duplicati, e non posso semplicemente drop_duplicates(), dato che questo perderà i dati).

Mi piacerebbe essere in grado di forzare le righe che hanno lo stesso valore [data, nome] in una singola riga, se possono essere convertite correttamente in base a determinati valori come NaN (simile al comportamento di combine_first()) . Per esempio, quanto sopra potrebbe finire al

date, name, value1, value2, value3, value4 
1/1/2001,ABC,1,1,2,35 

Se due valori sono diversi e uno non è NaN, le due file non devono essere convergenti (questo probabilmente sarebbe un errore che avrei bisogno di follow-up su).

(Per estendere l'esempio precedente, si possono infatti essere un numero arbitrario di linee - dato un numero arbitrario di colonne -. Che dovrebbe essere in grado di essere convergenti in un'unica linea)

Questo sente come un problema che dovrebbe essere molto risolvibile tramite panda, ma ho difficoltà a trovare una soluzione elegante.

risposta

11

Immaginiamo di avere qualche funzione combine_it che, dato un insieme di righe che avrebbe valori duplicati, restituisce una singola riga. In primo luogo, il gruppo da date e name:

grouped = data.groupby(['date', 'name']) 

Poi basta applicare la funzione di aggregazione e braccio il gioco è fatto:

result = grouped.agg(combine_it) 

È possibile anche fornire diverse funzioni di aggregazione per le diverse colonne passando agg un ditt.

+0

Grazie, che sicuramente riduce un passaggio chiave. C'è un idioma particolarmente efficiente con cui fare questo? Nella mia esperienza (e test iniziale usando il tuo suggerimento), .agg() può causare un'esecuzione veramente lenta (probabilmente non sorprendentemente). Forse inevitabile? – severian

+0

Forse? Si può provare a usare le funzioni incorporate di numpy ("sum", "max", ecc.) Per velocizzarlo (che usa le funzioni cythonized). Questo è probabilmente al di fuori del normale caso d'uso per groupby perché probabilmente si avranno molti gruppi relativi alla dimensione totale di DataFrame. –

+0

Beh, salvo un'altra risposta, almeno so di non aver perso nulla di troppo ovvio ... – severian

0

Se non si dispone di valori di campo numerici, l'aggregazione con conteggio, min, somma ecc. Non sarà né possibile né sensata. Tuttavia, potresti comunque voler comprimere i record duplicati in singoli record (ad esempio) in base a una o più chiavi primarie.

# Firstly, avoid Nan values in the columns you are grouping on! 
df[['col1', 'col2']] = df[['col1', 'col2']].fillna('null') 


    # Define your own customized operation in pandas agg() function 
df = df.groupby(['col1', 'col2']).agg({'SEARCH_TERM':lambda x: ', '.join(tuple(x.tolist())), 

            'HITS_CONTENT':lambda x: ', '.join(tuple(x.tolist()))} 
            ) 

gruppo da una o più colonne e collasso valori valori convertirli prima, per elencare, poi a tupla e infine a stringa. Se preferisci puoi anche tenerli come lista o tupla memorizzati in ogni campo o applicare con il agg. funzione e un dizionario operazioni molto diverse per colonne diverse.

Problemi correlati