2016-07-13 23 views
5

Ho un file di input con colonne note, diciamo due colonne Name e Sex. A volte si ha la riga di intestazione Name,Sex, ed a volte non:Panda read_csv senza sapere se l'intestazione è presente

1.csv:

Name,Sex 
John,M 
Leslie,F 

2.csv:

John,M 
Leslie,F 

Conoscere l'identità del colonne in anticipo, c'è un buon modo per gestire entrambi i casi con lo stesso comando read_csv? Fondamentalmente, voglio specificare names=['Name', 'Sex'] e poi ho inferire header=0 solo quando l'intestazione è lì. Meglio che posso venire in mente è:

  • 1) leggere la prima riga del file prima di fare read_csv, e impostare parametri in modo appropriato.

  • 2) Basta fare df = pd.read_csv(input_file, names=['Name', 'Sex']), quindi controllare se la riga dello zeroeth è identica alla testa, e se quindi rilasciarlo (e poi magari avere rinumerare le righe).

Ma questo non mi sembra un caso insolito per me. C'è un modo integrato per farlo con read_csv a cui non ho pensato?

risposta

5

utilizzando nuova funzione - selection by callable:

cols = ['Name','Sex'] 

df = (pd.read_csv(filename, header=None, names=cols) 
     [lambda x: np.ones(len(x)).astype(bool) 
       if (x.iloc[0] != cols).all() 
       else np.concatenate([[False], np.ones(len(x)-1).astype(bool)])] 
) 

utilizzando .query() metodo:

df = (pd.read_csv(filename, header=None, names=cols) 
     .query('Name != "Name" and Sex != "Sex"')) 

non sono sicuro che questo è il modo più elegante, ma questo dovrebbe funzionare così:

df = pd.read_csv(filename, header=None, names=cols) 

if (df.iloc[0] == cols).all(): 
    df = df[1:].reset_index(drop=True) 
+1

Grazie per tutte le opzioni! L'ultima versione mi sembra ancora più pulita, quindi suppongo che userò questo approccio. Lascerò la domanda aperta per ora e accetto entro un paio di giorni se non si presenta nient'altro. – leekaiinthesky

Problemi correlati