Csv 到 json 通过相同的键-python

Posted

技术标签:

【中文标题】Csv 到 json 通过相同的键-python【英文标题】:Csv to json by the same key-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。 【参考方案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)

【讨论】:

以上是关于Csv 到 json 通过相同的键-python的主要内容,如果未能解决你的问题,请参考以下文章

为 CSV 阅读器引用 Python 字典中的键

python中 列表导入到字典 出现相同的键,如何将值相加

Python爬虫编程思想(157):使用Scrapy从CSV格式转换到JSON格式

Python爬虫编程思想(157):使用Scrapy从CSV格式转换到JSON格式

Python爬虫编程思想(157):使用Scrapy从CSV格式转换到JSON格式

将嵌套的键/值和嵌套列表合并到 json