2016-05-17 4 views
0

So bekomme ich eine CSV-in API-Anforderung, ist-das Format der CSVCSV Lesen für gleiche Kopf- und getrennt in dict

"id","loc_name","qty","loc_name","qty" "NM001","HLR","10","KBD","20" "NM003","KMG","15","SLD","25"

und ich möchte ein dict in diesem Format: {"NM001":{'HLR':'10', 'KBD':'20'}, "NM003":{"KMG": "15", "SLD": "25"}}

versucht Code-

field_names = next(csv.reader(csv_file,delimiter=",")) csv_file_handler = csv.DictReader(csv_file,delimiter=",",fieldnames=field_names) for each_row in islice(csv_file_handler, 1, None): print each_row

  • hier csv_file ist die Datei, die ich in der Antwort bekomme.

result = {'id': 'NM001', 'loc_name': 'KBD', 'qty': '20'} {'id': 'NM003', 'loc_name': 'SLD', 'qty': '25'}

das Problem in csv.DictReader ist, dass es nur den letzten Wert zurück, da die Header gleich sind.

Antwort

1

I pandas Modul bin mit csv Dateien für die Handhabung. Ich würde dieses Problem angeht wahrscheinlich auf diese Weise (wenn auch nicht die beste Art und Weise möglich, nehme ich an und nicht die beste Art und Weise in Pandas. Aber hey, es funktioniert.

import pandas as pd 
# read the csv as DataFrame, probably there is a way to get it from 
# the API directly without saving to a file 
# specify header as the first row 
df = pd.read_csv("test.csv", header=0) 
# empty dict 
d = {} 
# iterate over lines, I use this way, but I don't like it in fact 
for i, key_id in enumerate(df["id"]): 
    # assign the values the way you want it 
    # however you need to specify it by names 
    # or indices 
    d[key_id.strip()] = {df.loc[i, "loc_name"]:df.loc[i, "qty"], 
         df.loc[i, "loc_name.1"]:df.loc[i, "qty.1"]} 
print(d) 
#{'"NM003"': {'SLD': 25, 'KMG': 15}, '"NM001"': {'HLR': 10, 'KBD': 20}} 

Wenn Sie dies wollen mit zusätzlichen Spalten arbeiten (was muss kommen in Paar: key:val), dann können Sie df.ix[<row>,<col>] verwenden und iterieren zuerst über Zeilen (wie bisher) und dann über Spalten (hinzufügen, wenn nur nicht nan Werte hinzugefügt werden):

for i, key_id in enumerate(df["id"]): 
    # create empty dict 
    d[key_id.strip()] = {} 
    # a less python more C-like syntax 
    # go through cols, skip the first and step is 2 
    for j in range(1, len(df.columns), 2): 
     # if there is some entry 
     if not pd.isnull(df.ix[i,j]): 
      d[key_id.strip()][df.ix[i, j]] = df.ix[i, j+1] 
+0

sieht gut aus, aber was ist, wenn die Größe csv changes.Wie Sie es tun, durch harte codind '{df.loc [i," loc_name "]: df.loc [i," qty "], df.loc [i," l oc_name.1 "]: df.loc [i," qty.1 "]}' können wir das ignorieren? –

+0

Das hängt davon ab, was "die Größe von CSV ändert" bedeutet. Beziehen Sie sich auf Zeilen oder Spalten? Sie können 'df.ix [, ]' 'verwenden und int-Indizes verwenden und diesen Code dafür austauschen:' {df.ix [i, 1]: df.ix [i, 2], df.ix [i, 3]: df.ix [i, 4]} '. – quapka

+0

kann es N Anzahl von Zeilen oder Spalten geben. Also muss das iterieren. –

1

Kannst du nicht tun es wie folgt aus:

result = dict() 
for line in file: 
    line = line.split('","') 
    id = line[0][1:] 
    l_n_1 = line[1] 
    qty_1 = line[2] 
    l_n_2 = line[3] 
    qty_2 = line[4][:-1] 

    if(id != "id"): 
     result[id] = {l_n_1: qty_1, l_n_2: qty_2} 

print(result) 

Dies funktioniert und behandelt es wie Sie wollen.

Ich öffnete eine lokale Datei, aber es sollte auch von einer API-Anfrage möglich sein. Meine Datei sah wie folgt aus:

"id","loc_name","qty","loc_name","qty" 
"NM001","HLR","10","KBD","20" 
"NM003","KMG","15","SLD","25" 
0

Angenommen, Sie haben

results = [{'id': 'NM001', 'loc_name': 'KBD', 'qty': '20'}, {'id': 'NM003', 'loc_name': 'SLD', 'qty': '25'}] 

Sie bekommen, was Sie wollen von: -

result_dicts = { res['id']: res for res in results } 
for _, result_dict in result_dicts.items(): 
    result_dict.pop('id')