我一直在尝试用大文件进行数据整理练习,我选择了这个大文件,我在谷歌上搜索了一下,发现它在Python中相当简单,但我还不是最熟悉编码的人。所以我需要更多关于如何正确设置它的解释(像我五岁一样解释)。我已经完成了“用另一个名称保存文件以对其进行格式化”,但这就是它的格式化方式。
我不确定从我找到的Python代码中它是否应该是这样的,所以,如果有人可以帮助或向我澄清它。这是我找到的代码。
import json
import csv
with open('G:\Akhil\jsonoutput.json') as json_file:
jsondata = json.load(json_file)
data_file = open('G:\Akhil\jsonoutput.csv', 'w', newline='')
csv_writer = csv.writer(data_file)
count = 0
for data in jsondata:
if count == 0:
header = data.keys()
csv_writer.writerow(header)
count += 1
csv_writer.writerow(data.values())
data_file.close()
该代码正确吗?如果是,我该如何编辑它来转换它?如何下载并保存该文件以便在 Excel 上打开它?预先感谢
这对我来说是新事物,所以我想弄清楚,但我陷入了困境,因为我什至不确定 JSON 文件的格式是否正确
将任何内容(JSON、XML...)转换为 CSV 时,您需要清楚地了解您希望最终的 CSV 是什么样子。
对于 JSON,这只是平面对象的列表:
[
{"id": "1", "name": "foo", "score": 0},
{"id": "2", "name": "bar", "score": 0},
{"id": "1", "name": "foo", "score": 1},
{"id": "3", "name": "baz", "score": 0},
{"id": "3", "name": "baz", "score": 2}
]
我们可以轻松地将其可视化为以下 CSV:
id,name,score
1,foo,0
2,bar,0
1,foo,1
3,baz,0
3,baz,2
以及进行转换的 Python 代码:
import csv
import json
with open("input_flat.json") as f:
data = json.load(f)
with open("output_flat.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
for row in data:
writer.writerow(row)
由于 JSON 只是一个对象数组,或者用 Python 术语来说,就是 字典列表,我们可以使用 DictWriter 在
row
中编写每个单独的字典 (data
)。我们还必须使用它将在各个字典中查找的字段名来创建 DictWriter,因此 data[0].keys()
从数据中的第一个字典中获取键。
对于 JSON 来说更像你的,我们有一个嵌套结构,有点像:
{
"1": {
"name": "foo",
"data": [
{"score": 0},
{"score": 1}
]
},
"2": {
"name": "bar",
"data": [
{"score": 0}
]
},
"3": {
"name": "baz",
"data": [
{"score": 0},
{"score": 2}
]
}
}
CSV 看起来应该与上面的 CSV 相似吗? (只有你,亲爱的程序员,可以回答这个问题)如果是这样,我们仍然可以像上面一样使用 DictWriter,但是现在 row-dict 没有交给我们,我们需要自己构建它:
with open("input_nested.json") as f:
all_data = json.load(f)
rows = []
for id_, obj in all_data.items():
for data in obj["data"]:
row = {
"id": id_,
"name": obj["name"],
"score": data["score"],
}
rows.append(row)
with open("output_nested.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=rows[0].keys())
writer.writeheader()
for row in rows:
writer.writerow(row)
加载 JSON 时,我将数据重命名为 all_data。接下来,我们将 all_data 中的每个对象及其子对象(在“data”键下)“展平”为一行;或者,从结构的底部“构建”行字典。 (我还必须小心并在外循环中命名我的变量 id_
,因为
id
是 Python 中的保留词。)这给了我们:id,name,score
1,foo,0
1,foo,1
2,bar,0
3,baz,0
3,baz,2
由于排序原因,与上面的不完全相同,但几乎相等。
尽管搜索 OWID 大约 20 分钟,但我无法找到您使用的实际 JSON,但从您的屏幕截图来看,这些结构非常相似。如果您可以遵循简单的 foo-bar-baz 示例并了解嵌套 JSON 的结构,以及如何在 Python 中使用它,您就可以开始设计最终所需的 CSV。
for data in jsondata
只是键,而不是要写入 CSV 的值。所以,for循环不起作用。
如果确实如此,那么count = 0
事情就不太对劲了。您将标题写两次。通过将
values()
写入 CSV,您可以假设每个字典值始终以相同的顺序写入。但 JSON 字典没有排序,所以这个假设不起作用。最好使用处理字典的csv.DictWriter
。如果这是众所周知的 JSON 格式,最好在 Python 脚本中对标头进行硬编码。这将帮助脚本检测错误。但在这个例子中,我假设总是至少有一个条目,并且任何条目键都可以用于标题。
import json
import csv
# json data is a dict whose values are dicts to be written to a csv.
with open('G:\Akhil\jsonoutput.json') as json_file:
jsondata = json.load(json_file)
# assuming all dicts have the same keys, grab the first one as header
fieldnames = next(jsondata.values())
with open('G:\Akhil\jsonoutput.csv', 'w', newline='') as data_file:
csv_writer = csv.DictWriter(data_file, fieldnames)
csv_writer.writerows(jsondata.values())
请注意,此代码忽略外部字典的键(“AFG”等)。如果您也需要该信息,可以在写入 CSV 之前将其添加到内部字典中。