【问题标题】:Python Convert CSV to Dictionary of ListsPython 将 CSV 转换为列表字典
【发布时间】:2020-01-03 22:29:30
【问题描述】:

我有一个如下所示的 CSV 文件:

compound, x1data,y1data,x2data,y2data
a,1,2,3,4
a,9,10,11,12
b,5,6,7,8
b,4,5,6,7

我想创建一个列表字典,其中复合是键,对于每个复合,我得到一个 x1data、y1data、x2data 和 y2data 的列表。

我相信它看起来像这样:

my_dict = {
    'a': {'x1data':[1,9],'y1data':[2,10],'x2data':[3,11],'y2data':[4,12]},
    'b':{'x1data':[5,4],'y1data':[6,5],'x2data':[7,6],'y2data':[8,7]}
}

最终,我想为每种化合物绘制 x1data 与 y1data 以及 x2data 与 y2data 的图。

我已经尝试过这个方法,它正确地制作了一个字典,其中键是化合物,但它没有给我一个值列表(只是 csv 中的最后一个值。

my_dict = {}
with open(filename, 'r') as infile:
    reader = csv.DictReader(infile)
    for row in reader:
        key = row.pop('compound')
        my_dict[key] = row

【问题讨论】:

    标签: python csv dictionary


    【解决方案1】:

    这是一种无需任何库的方法。

    f = open('f.csv', 'rb')
    next(f)
    mydict = {}
    for row in f:
    
        compound,x1data,y1data,x2data,y2data = row.strip().split(',')
        x1data,y1data,x2data,y2data = int(x1data),int(y1data),int(x2data),int(y2data)
        if compound not in mydict:
            mydict[compound] = { 'x1data' : [], 'y1data' : [], 'x2data' : [], 'y2data' : [] }
    
    
        mydict[compound]['x1data'].append(x1data)
        mydict[compound]['y1data'].append(y1data)
        mydict[compound]['x2data'].append(x2data)
        mydict[compound]['y2data'].append(y2data)
    }
    f.close()
    
    print mydict
    

    给你:

    {'a': {'x2data': [3, 11], 'y2data': [4, 12], 'y1data': [2, 10], 'x1data': [1, 9]}, 'b': {'x2data': [7, 6], 'y2data': [8, 7], 'y1data': [6, 5], 'x1data': [5, 4]}}
    

    【讨论】:

      【解决方案2】:

      您可以使用标准库中的collections.defaultdict

      from collections import defaultdict as dd
      
      import csv
      
      my_dict = dd(lambda: dd(list))
      
      with open("test.csv", 'r') as f:
          reader = csv.DictReader(f)
      
          for row in reader:
              for key in reader.fieldnames[1:]:
                  my_dict[row.get("compound")][key].append(row[key])
      

      从技术上讲,您在这里得到的不是dict。不过,您可以以同样的方式使用它。

      如果你想打印,那就有点牵强了:

      from pprint import pprint
      
      # ...
      
      pprint({k: dict(v) for k, v in dict(my_dict).items()})
      

      这给出了:

      {'a': {'x1data': ['1', '9'],
             'x2data': ['3', '11'],
             'y1data': ['2', '10'],
             'y2data': ['4', '12']},
       'b': {'x1data': ['5', '4'],
             'x2data': ['7', '6'],
             'y1data': ['6', '5'],
             'y2data': ['8', '7']}}
      

      【讨论】:

      • 谢谢!这对我来说效果很好,我很欣赏它对于不同的数据标题、列数和键等都很灵活。
      【解决方案3】:

      这是一个不依赖于 csv 库的解决方案,它应该与任意大小的标头一起使用。

      with open("dat.csv", 'r') as f:
          lines = f.read().splitlines()
      
      headers = lines.pop(0).split(",")[1:] # names of the columns
      results = {}
      for line in lines:
        line = line.split(",")
        if line[0] not in results:
          results[line[0]] = {header:[] for header in headers}
        for i, header in enumerate(headers):
          results[line[0]][header].append(line[i+1])
          # for ints: results[line[0]][header].append(int(line[i+1]))
      
      print(results)
      

      输出:

      {'a': {'x2data': ['3', '11'], 'y2data': ['4', '12'], 'y1data': ['2', '10'], 'x1data': ['1', '9']}, 'b': {'x2data': ['7', '6'], 'y2data': ['8', '7'], 'y1data': ['6', '5'], 'x1data': ['5', '4']}}
      

      我所做的唯一更改是在提供的标题中删除一个空格(尽管它可以工作)。

      【讨论】:

        【解决方案4】:

        你可以使用itertools.groupby:

        import csv, itertools
        [_, *hs], *data = csv.reader(open('filename.csv'))
        r = [(a, [list(map(int, i[1:])) for i in b]) for a, b in itertools.groupby(data, key=lambda x:x[0])]
        final_result = {a:dict(zip(hs, map(list, zip(*b)))) for a, b in r}
        

        输出:

        {'a': {'x1data': [1, 9], 'y1data': [2, 10], 'x2data': [3, 11], 'y2data': [4, 12]}, 'b': {'x1data': [5, 4], 'y1data': [6, 5], 'x2data': [7, 6], 'y2data': [8, 7]}}
        

        【讨论】:

          猜你喜欢
          • 2021-01-28
          • 2014-04-24
          • 2019-04-11
          • 2015-07-23
          • 2018-06-23
          • 2018-12-09
          • 2021-07-31
          • 1970-01-01
          • 2018-01-14
          相关资源
          最近更新 更多