2017-08-24 3 views
0

erstmals Plakat lange Zeit LeserWie eine Liste in einem verschachtelten Wörterbuch aus einer CSV-

ich eine csv haben zu definieren, die auf diese Weise formatiert wird, bemerken, dass es mehrere Datensätze gleichzeitig und innerhalb dieses Zeitraums sind, gibt es mehrere Datensätze mit demselben data4 Wert:

Time,data1,data2,data3,data4 
8/12/2017 8:37:11.719,4435441.97983871,321106.049167927,1260.354,64 
8/12/2017 8:37:11.719,4435451.97715054,321346.085476551,1260.354,60 
8/12/2017 8:37:11.719,4435461.97446237,321096.047655068,1260.354,64 
8/12/2017 8:37:11.719,4435461.97446237,321106.049167927,1260.354,64 
8/12/2017 8:37:26.919,4436121.79704301,324496.562027231,1260.354,96 
8/12/2017 8:37:26.919,4436121.79704301,324506.563540091,1260.354,96 
8/12/2017 8:37:26.919,4436121.79704301,324546.569591528,1260.354,56 
8/12/2017 8:37:26.919,4436121.79704301,324646.584720121,1260.354,64 

ich versuche, eine Funktion zu schreiben, diese csv in einem verschachtelten Wörterbuch zu lesen, die die Zeitspalte und die data4 Spalte als verschachtelte Schlüssel verwendet. Was ich bisher habe, ist dies:

def build_dict(source_file): 
    new_dict = defaultdict(dict) 

    headers = ['Time','data1','data2','data3','data4'] 
    with open(source_file, 'rb') as fp: 
     reader = csv.DictReader(fp, fieldnames=headers, dialect='excel', 
           skipinitialspace=True) 
     for rowdict in reader: 
      if None in rowdict: 
       del rowdict[None] 
      Time = rowdict.pop("Time") 
      data4 = int(rowdict.pop("data4")) 
      dict[Time][data4] = rowdict 
    return dict(new_dict) 

Welche zurück:

new_dict = { 
    '8/12/2017 8:37:11.719' : { 
     64: {'data3': '1260.354', 'data1': '4435441.97983871', 'data2': '321106.049167927'}, 
     60: {'data3': '1260.354', 'data1': '4435451.97715054', 'data2': '321346.085476551'} 
    } 
} 

Es ist fast tut, was ich brauche, aber es überschreibt die vorherigen Zeilendaten mit Zeit und data4 sind die gleichen. Ich denke, ich muss Daten1, Daten2 und Daten3 in einer Liste speichern, aber nicht sicher, wie es geht. Diese

ist das, was ich würde mein Wörterbuch mag wie so aussehen, dass pro Zeiteinheit kann ich Gruppendaten von data4 Werte:

new_dict = { 
    '8/12/2017 8:37:11.719' : { 
     60 : [ 
      {'data1': '4435451.97715054', 'data2': '321346.085476551', 'data3': '1260.354'} 
      ], 
     64 : [ 
      {'data1': '4435441.97983871', 'data2': '321106.049167927', 'data3': '1260.354'}, 
      {'data1': '4435461.97446237', 'data2': '321096.047655068', 'data3': '1260.354'}, 
      {'data1': '4435461.97446237', 'data2': '321106.049167927', 'data3': '1260.354'} 
      ] 
     } 
    } 

Jede Hilfe Sie würde sehr geschätzt werden zur Verfügung stellen kann.

Antwort

0

Nun ist es klassischer Anwendungsfall: Gruppierung

So ist, desto einfacher itertools.groupby gruppiert Ihre dict von "Time" zu verwenden ist.

reader = csv.DictReader(fp, dialect='excel', skipinitialspace=True) 
headers = next(reader) 
new_dict = {} 
for group, records in itertools.groupby(reader, key=operator.itemgetter('Time')): 
    new_dict[group] = list(records) 

Sie erhalten:

{'8/12/2017 8:37:11.719': [{'Time': '8/12/2017 8:37:11.719', 
          'data1': '4435451.97715054', 
          'data2': '321346.085476551', 
          'data3': '1260.354', 
          'data4': '60'}, 
          {'Time': '8/12/2017 8:37:11.719', 
          'data1': '4435461.97446237', 
          'data2': '321096.047655068', 
          'data3': '1260.354', 
          'data4': '64'}, 
          {'Time': '8/12/2017 8:37:11.719', 
          'data1': '4435461.97446237', 
          'data2': '321106.049167927', 
          'data3': '1260.354', 
          'data4': '64'}], 
'8/12/2017 8:37:26.919': [{'Time': '8/12/2017 8:37:26.919', 
          'data1': '4436121.79704301', 
          'data2': '324496.562027231', 
          'data3': '1260.354', 
          'data4': '96'}, 
          {'Time': '8/12/2017 8:37:26.919', 
          'data1': '4436121.79704301', 
          'data2': '324506.563540091', 
          'data3': '1260.354', 
          'data4': '96'}, 
          {'Time': '8/12/2017 8:37:26.919', 
          'data1': '4436121.79704301', 
          'data2': '324546.569591528', 
          'data3': '1260.354', 
          'data4': '56'}, 
          {'Time': '8/12/2017 8:37:26.919', 
          'data1': '4436121.79704301', 
          'data2': '324646.584720121', 
          'data3': '1260.354', 
          'data4': '64'}]} 

Sie können auch ein Verständnis Wörterbuch verwenden:

new_dict = {group: list(records) 
      for group, records in itertools.groupby(reader, key=operator.itemgetter('Time'))} 

Wenn Sie zu einer Gruppe mit "Zeit" und "data4" benötigen, müssen Sie ändern die Gruppierung Schlüssel:

for group, records in itertools.groupby(reader, key=lambda v: (v["Time"], int(v["data4"]))): 
    new_dict[group] = list(records) 

Das Ergebnis ist:

{('8/12/2017 8:37:11.719', 60): [{'Time': '8/12/2017 8:37:11.719', 
            'data1': '4435451.97715054', 
            'data2': '321346.085476551', 
            'data3': '1260.354', 
            'data4': '60'}], 
('8/12/2017 8:37:11.719', 64): [{'Time': '8/12/2017 8:37:11.719', 
            'data1': '4435461.97446237', 
            'data2': '321096.047655068', 
            'data3': '1260.354', 
            'data4': '64'}, 
           {'Time': '8/12/2017 8:37:11.719', 
            'data1': '4435461.97446237', 
            'data2': '321106.049167927', 
            'data3': '1260.354', 
            'data4': '64'}], 
('8/12/2017 8:37:26.919', 56): [{'Time': '8/12/2017 8:37:26.919', 
            'data1': '4436121.79704301', 
            'data2': '324546.569591528', 
            'data3': '1260.354', 
            'data4': '56'}], 
('8/12/2017 8:37:26.919', 64): [{'Time': '8/12/2017 8:37:26.919', 
            'data1': '4436121.79704301', 
            'data2': '324646.584720121', 
            'data3': '1260.354', 
            'data4': '64'}], 
('8/12/2017 8:37:26.919', 96): [{'Time': '8/12/2017 8:37:26.919', 
            'data1': '4436121.79704301', 
            'data2': '324496.562027231', 
            'data3': '1260.354', 
            'data4': '96'}, 
           {'Time': '8/12/2017 8:37:26.919', 
            'data1': '4436121.79704301', 
            'data2': '324506.563540091', 
            'data3': '1260.354', 
            'data4': '96'}]} 

Wenn Sie zwei Gruppierungsebenen müssen: zuerst "Time", dann "data4", benötigen Sie 2 Schlaufen:

new_dict = {} 
for group1, records1 in itertools.groupby(reader, key=operator.itemgetter("Time")): 
    new_dict[group1] = {} 
    for group2, records2 in itertools.groupby(records1, key=lambda v: int(v["data4"])): 
     new_dict[group1][group2] = list(records2) 

Das Ergebnis:

{'8/12/2017 8:37:11.719': {60: [{'Time': '8/12/2017 8:37:11.719', 
           'data1': '4435451.97715054', 
           'data2': '321346.085476551', 
           'data3': '1260.354', 
           'data4': '60'}], 
          64: [{'Time': '8/12/2017 8:37:11.719', 
           'data1': '4435461.97446237', 
           'data2': '321096.047655068', 
           'data3': '1260.354', 
           'data4': '64'}, 
           {'Time': '8/12/2017 8:37:11.719', 
           'data1': '4435461.97446237', 
           'data2': '321106.049167927', 
           'data3': '1260.354', 
           'data4': '64'}]}, 
'8/12/2017 8:37:26.919': {56: [{'Time': '8/12/2017 8:37:26.919', 
           'data1': '4436121.79704301', 
           'data2': '324546.569591528', 
           'data3': '1260.354', 
           'data4': '56'}], 
          64: [{'Time': '8/12/2017 8:37:26.919', 
           'data1': '4436121.79704301', 
           'data2': '324646.584720121', 
           'data3': '1260.354', 
           'data4': '64'}], 
          96: [{'Time': '8/12/2017 8:37:26.919', 
           'data1': '4436121.79704301', 
           'data2': '324496.562027231', 
           'data3': '1260.354', 
           'data4': '96'}, 
           {'Time': '8/12/2017 8:37:26.919', 
           'data1': '4436121.79704301', 
           'data2': '324506.563540091', 
           'data3': '1260.354', 
           'data4': '96'}]}} 
+0

Wow, zwei gute Antworten und so schnell. Ich habe dies als Antwort markiert, weil es für mich einfacher schien, aber nicht bedeutet, dass der andere es nicht war, danke für die Hilfe – Dustman

0

Ich empfehle die Verwendung der Pandas-Bibliothek, da sie eine gute Möglichkeit bietet, CSV-Dateien über den Pandas-Dataframe zu lesen und zu gruppieren.

import pandas as pd 

# read the CSV file 
df = pd.read_csv("test.csv") 

# group by the desired columns 
gb = df.groupby(['Time', 'data4']) 

Dies gibt ein GroupBy Objekt während des Schlüssel ein Tupel des Zeitstempels und date4 und der Wertes für jede Gruppe ist, ist ein neuer Datenrahmen, die Spiele/Wert enthält. Jetzt haben Sie drei Möglichkeiten:

# option 1 
list(gb) 

Welche gibt Ihnen:

[(('8/12/2017 8:37:11.719', 60), 
         Time   data1   data2  data3 data4 
    1 8/12/2017 8:37:11.719 4.435452e+06 321346.085477 1260.354  60), 
(('8/12/2017 8:37:11.719', 64), 
         Time   data1   data2  data3 data4 
    0 8/12/2017 8:37:11.719 4.435442e+06 321106.049168 1260.354  64 
    2 8/12/2017 8:37:11.719 4.435462e96.047655 1260.354  64 
    3 8/12/2017 8:37:11.719 4.435462e+06 321106.049168 1260.354  64), 
(('8/12/2017 8:37:26.919', 56), 
         Time   data1   data2  data3 data4 
    6 8/12/2017 8:37:26.919 4.436122e+06 324546.569592 1260.354  56), 
(('8/12/2017 8:37:26.919', 64), 
         Time   data1   data2  data3 data4 
    7 8/12/2017 8:37:26.919 4.436122e+06 324646.58472 1260.354  64), 
(('8/12/2017 8:37:26.919', 96), 
         Time   data1   data2  data3 data4 
    4 8/12/2017 8:37:26.919 4.436122e+06 324496.562027 1260.354  96 
    5 8/12/2017 8:37:26.919 4.436122e+06 324506.563540 1260.354  96)] 

Sie können auch ein Wörterbuch verwenden, die ein vergleichbares Ergebnis produziert:

# option 2 
dict(list(gb)) 

Oder Sie iterieren die Gruppen und Tun Sie, was Sie mit den Reihen jeder Gruppe machen möchten

# option 3 
result = {} 
for name, df_group in gb: 
    timestamp, date4 = name 
    outer_dict = result.get(timestamp, {}) 
    inner_dict = df_group.T.to_dict() 
    #inner_dict = df_group.to_dict(orient="index") 
    #inner_dict = df_group.values.tolist() 

    outer_dict[date4] = inner_dict 
    result[timestamp] = outer_dict 

print(result) 

Welche gibt Ihnen das Folgende. Sie können mit dem Löschen einiger Spalten wie dem Index, dem Zeitstempel und dem Datum4 herumspielen.

{'8/12/2017 8:37:11.719': {60: {1: {'Time': '8/12/2017 8:37:11.719', 
    'data1': 4435451.97715054, 
    'data2': 321346.08547655103, 
    'data3': 1260.354, 
    'data4': 60}}, 
    64: {0: {'Time': '8/12/2017 8:37:11.719', 
    'data1': 4435441.97983871, 
    'data2': 321106.049167927, 
    'data3': 1260.354, 
    'data4': 64}, 
    2: {'Time': '8/12/2017 8:37:11.719', 
    'data1': 4435461.97446237, 
    'data2':96.047655068, 
    'data3': 1260.354, 
    'data4': 64}, 
    3: {'Time': '8/12/2017 8:37:11.719', 
    'data1': 4435461.97446237, 
    'data2': 321106.049167927, 
    'data3': 1260.354, 
    'data4': 64}}}, 
'8/12/2017 8:37:26.919': {56: {6: {'Time': '8/12/2017 8:37:26.919', 
    'data1': 4436121.79704301, 
    'data2': 324546.569591528, 
    'data3': 1260.354, 
    'data4': 56}}, 
    64: {7: {'Time': '8/12/2017 8:37:26.919', 
    'data1': 4436121.79704301, 
    'data2': 324646.584720121, 
    'data3': 1260.354, 
    'data4': 64}}, 
    96: {4: {'Time': '8/12/2017 8:37:26.919', 
    'data1': 4436121.79704301, 
    'data2': 324496.56202723103, 
    'data3': 1260.354, 
    'data4': 96}, 
    5: {'Time': '8/12/2017 8:37:26.919', 
    'data1': 4436121.79704301, 
    'data2': 324506.56354009104, 
    'data3': 1260.354, 
    'data4': 96}}}} 

Ich hoffe, Sie haben die Idee.

Verwandte Themen