【问题标题】:Csv to json by the same key-pythonCsv 到 json 通过相同的键-python
【发布时间】:2018-12-14 23:03:55
【问题描述】:

我有一个大的 csv 文件(大约 1GB),我想通过以下方式将其转换为 json 文件:

csv 文件的结构如下:

标头:tid;inkey;outkey;value

价值观:

tid1;inkey1;outkey1;value1
tid1;inkey2;outkey2;value2
tid2;inkey2;outkey3;value2
tid2;inkey4;outkey3;value2

等等

想法是将这个csv转换为具有以下结构的json,基本上是按“tid”对所有内容进行分组:

{
"tid1":  {
    "inkeys":["inkey1", "inkey2"],
    "outkeys":["outkey1", "outkey2"]
         }
}

我可以想象如何处理普通的 python 字典和列表,但我的问题也是我必须处理的大量数据。我想 pandas 可以在这里提供帮助,但我仍然对这个工具很困惑。

【问题讨论】:

  • 1gb 不是很大。你真的遇到过性能问题吗?对我来说,这听起来不像是熊猫的工作。
  • 到目前为止你尝试了什么?你在一个小的 csv 上写了一些代码吗?我们可以帮助您优化代码/了解您的错误,但您必须自己动手!
  • 提示:尝试在python字典中创建相同的结构,应该是一个简单的任务。
  • tid 值是否“分组” - 即您能否确定一旦您在文件中从tid1 转到tid2,就不会再出现tid1方式?如果是这种情况,您可以逐行读取文件,编写一个字典,并在 tid 更改后附加到 JSON。

标签: python json pandas csv dictionary


【解决方案1】:

我认为这应该直接用于标准 Python 数据结构,例如 defaultdict。除非您的内存非常有限,否则我认为没有理由使用直截了当的方法来解决 1gb 文件的问题。

类似(未测试):

from collections import defaultdict
import csv 
import json

out_data = defaultdict(lambda: {"inkeys": [], "outkeys": [], "values": []})
with file("your-file.csv") as f:
    reader = csv.reader(f):
    for line in reader:
        tid, inkey, outkey, value = line
        out_data[tid]["inkeys"].append(inkey)
        out_data[tid]["outkeys"].append(outkey)
        out_data[tid]["values"].append(value)

print(json.dumps(out_data))

可能有一种更快或更高效的方式来使用 Pandas 或其他方式来执行此操作,但简单性和零依赖关系还有很长的路要走。

【讨论】:

    【解决方案2】:

    首先,您需要使用 pandas 并将您的 csv 读入数据框。假设 csv 保存在一个名为 my_file.csv 的文件中,然后您调用

    import pandas as pd    
    my_df = pd.read_csv('my_file.csv')
    

    然后您需要将此数据框转换为您指定的形式。以下调用会将其转换为具有指定结构的dict

    my_json = dict(my_df.set_index('tid1').groupby(level=0).apply(lambda  x : x.to_json(orient = 'records')))
    

    现在您可以根据需要将其导出到 json 文件

    import json
    with open('my_json.json', 'w') as outfile:
        json.dump(my_json, outfile)
    

    【讨论】:

      【解决方案3】:

      您可以将 Pandas 与 groupby 和字典理解一起使用:

      from io import StringIO
      import pandas as pd
      
      mystr = StringIO("""tid1;inkey1;outkey1;value1
      tid1;inkey2;outkey2;value2
      tid2;inkey2;outkey3;value2
      tid2;inkey4;outkey3;value2""")
      
      # replace mystr with 'file.csv'
      df = pd.read_csv(mystr, sep=';', header=None, names=['tid1', 'inkeys', 'outkeys'])
      
      # group by index
      grouper = df.groupby(level=0)
      
      # nested dictionary comprehension with selected columns
      res = {k: {col: v[col].tolist() for col in ('inkeys', 'outkeys')} for k, v in grouper}
      
      print(res)
      
      {'tid1': {'inkeys': ['outkey1', 'outkey2'], 'outkeys': ['value1', 'value2']},
       'tid2': {'inkeys': ['outkey3', 'outkey3'], 'outkeys': ['value2', 'value2']}}
      

      【讨论】:

        【解决方案4】:

        类似defaultdict()的其他回答:

        from collections import defaultdict
        
        d = defaultdict(lambda: defaultdict(list))
        
        with open('file.txt') as in_file:
            for line in in_file:
                tid, inkey, outkey, value = line.strip().split(';')
                d[tid]['inkeys'].append(inkey)
                d[tid]['outkeys'].append(outkey)
                d[tid]['values'].append(value)
        

        【讨论】:

          猜你喜欢
          • 2013-07-05
          • 1970-01-01
          • 1970-01-01
          • 2014-03-09
          • 2020-10-21
          • 1970-01-01
          • 2016-04-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多