2016-03-06 17 views
6

Ho file CSV con il seguente formato,pitone leggere file CSV con le intestazioni di righe e colonne in dizionario con due chiavi

,col1,col2,col3 
row1,23,42,77 
row2,25,39,87 
row3,48,67,53 
row4,14,48,66 

ho bisogno di leggere questo in un dizionario di due tasti in modo tale che

dict1['row1']['col2'] = 42 
dict1['row4']['col3'] = 66 

Se provo ad usare csv.DictReader con le opzioni predefinite

with open(filePath, "rb") as theFile: 
    reader = csv.DictReader(theFile, delimiter=',') 
    for line in reader: 
    print line 

ottengo il seguente Uscita

{'': 'row1', 'col2': '42', 'col3': '77', 'col1': '23'} 
{'': 'row2', 'col2': '39', 'col3': '87', 'col1': '25'} 
{'': 'row3', 'col2': '67', 'col3': '53', 'col1': '48'} 
{'': 'row4', 'col2': '48', 'col3': '66', 'col1': '14'} 

non sono sicuro di come elaborare questa uscita per creare il tipo di dizionario che mi interessa.

Per completezza, sarebbe anche utile se si può affrontare come per riscrivere il dizionario in un file csv con il formato sopraindicato

risposta

10

Utilizzando il modulo CSV:

import csv 
dict1 = {} 

with open("test.csv", "rb") as infile: 
    reader = csv.reader(infile) 
    headers = next(reader)[1:] 
    for row in reader: 
     dict1[row[0]] = {key: int(value) for key, value in zip(headers, row[1:])} 
+0

Che funziona e sembra elegante – WanderingMind

+1

Ho un problema, i valori nel dict sono stringhe e non interi. Come posso assicurarmi che i valori nel dizionario siano numeri interi – WanderingMind

+1

Vedere la mia modifica - basta chiamare 'int()' su ogni valore; tuttavia, ciò non riuscirà se neanche un singolo valore non può essere convertito in un numero intero. –

1

Il formato del file di input non è esattamente conveniente per analizzare con il modulo csv. Analizzerei le intestazioni separatamente, quindi analizzo il resto riga per riga, dividendo per ,, denudando e creando dizionari lungo il percorso. Il codice di lavoro:

from pprint import pprint 

d = {} 
with open("myfile.csv") as f: 
    headers = [header.strip() for header in next(f).split(",")[1:]] 

    for line in f: 
     values = [value.strip() for value in line.split(",")] 
     d[values[0]] = dict(zip(headers, values[1:])) 

pprint(d) 

Stampe:

{'row1': {'col1': '23', 'col2': '42', 'col3': '77'}, 
'row2': {'col1': '25', 'col2': '39', 'col3': '87'}, 
'row3': {'col1': '48', 'col2': '67', 'col3': '53'}, 
'row4': {'col1': '14', 'col2': '48', 'col3': '66'}} 
4

È possibile utilizzare pandas per questo, anche se è un po 'eccessivo. Il pro è che non c'è quasi nulla da codificare per ottenere il risultato atteso.

# Reading the file 
df = pd.read_csv('tmp.csv', index_col=0) 

# Creating the dict 
d = df.transpose().to_dict(orient='series') 

print(d['row1']['col2']) 
42 
+0

Questa risposta è elegante. Sfortunatamente sto lavorando su un server in cui Pandas non è presente. Preferisco non modificare alcuna impostazione di Python al momento, poiché potrebbe rompere gli altri pacchetti di interesse. – WanderingMind

Problemi correlati