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的主要内容,如果未能解决你的问题,请参考以下文章
Python爬虫编程思想(157):使用Scrapy从CSV格式转换到JSON格式
Python爬虫编程思想(157):使用Scrapy从CSV格式转换到JSON格式