gpt4 book ai didi

python - 嵌套的 json 到 csv - 通用方法

转载 作者:太空宇宙 更新时间:2023-11-03 11:23:54 25 4
gpt4 key购买 nike

我是 Python 的新手,我正在努力将嵌套的 json 文件转换为 cvs。为此,我首先加载 json,然后将其转换为使用 json_normalize 打印出漂亮输出的方式,然后使用 pandas 包将规范化部分输出到 cvs

我的示例 json:

[{
"_id": {
"id": "123"
},
"device": {
"browser": "Safari",
"category": "d",
"os": "Mac"
},
"exID": {
"$oid": "123"
},
"extreme": false,
"geo": {
"city": "London",
"country": "United Kingdom",
"countryCode": "UK",
"ip": "00.000.000.0"
},
"viewed": {
"$date": "2011-02-12"
},
"attributes": [{
"name": "gender",
"numeric": 0,
"value": 0
}, {
"name": "email",
"value": false
}],
"change": [{
"id": {
"$id": "1231"
},
"seen": [{
"$date": "2011-02-12"
}]
}]
}, {
"_id": {
"id": "456"
},
"device": {
"browser": "Chrome 47",
"category": "d",
"os": "Windows"
},
"exID": {
"$oid": "345"
},
"extreme": false,
"geo": {
"city": "Berlin",
"country": "Germany",
"countryCode": "DE",
"ip": "00.000.000.0"
},
"viewed": {
"$date": "2011-05-12"
},
"attributes": [{
"name": "gender",
"numeric": 1,
"value": 1
}, {
"name": "email",
"value": true
}],
"change": [{
"id": {
"$id": "1231"
},
"seen": [{
"$date": "2011-02-12"
}]
}]
}]

使用以下代码(这里我排除了嵌套部分):

import json
from pandas.io.json import json_normalize


def loading_file():
#File path
file_path = #file path here

#Loading json file
json_data = open(file_path)
data = json.load(json_data)
return data

#Storing avaliable keys
def data_keys(data):
keys = {}
for i in data:
for k in i.keys():
keys[k] = 1

keys = keys.keys()

#Excluding nested arrays from keys - hard coded -> IMPROVE
new_keys = [x for x in keys if
x != 'attributes' and
x != 'change']

return new_keys

#Excluding nested arrays from json dictionary
def new_data(data, keys):
new_data = []
for i in range(0, len(data)):
x = {k:v for (k,v) in data[i].items() if k in keys }
new_data.append(x)
return new_data

def csv_out(data):
data.to_csv('out.csv',encoding='utf-8')

def main():
data_file = loading_file()
keys = data_keys(data_file)
table = new_data(data_file, keys)
csv_out(json_normalize(table))

main()

我当前的输出看起来像这样:

| _id.id | device.browser | device.category | device.os |  ... | viewed.$date |
|--------|----------------|-----------------|-----------|------|--------------|
| 123 | Safari | d | Mac | ... | 2011-02-12 |
| 456 | Chrome 47 | d | Windows | ... | 2011-05-12 |
| | | | | | |

我的问题是我想将嵌套数组包含到 cvs 中,所以我必须将它们展平。我不知道如何使它通用,所以我在创建表时不使用字典 keys (numeric, id, name) 和 values。我必须让它具有通用性,因为 attributeschange 中的键数。因此,我希望有这样的输出:

| _id.id | device.browser | ... | attributes_gender_numeric | attributes_gender_value | attributes_email_value | change_id | change_seen |
|--------|----------------|-----|---------------------------|-------------------------|------------------------|-----------|-------------|
| 123 | Safari | ... | 0 | 0 | false | 1231 | 2011-02-12 |
| 456 | Chrome 47 | ... | 1 | 1 | true | 1231 | 2011-02-12 |
| | | | | | | | |

提前致谢!非常欢迎任何有关如何改进我的代码并使其更高效的提示。

最佳答案

感谢 Amir Ziai 的精彩博文,您可以找到它 here我设法以平面表格的形式输出我的数据。具有以下功能:

#Function that recursively extracts values out of the object into a flattened dictionary
def flatten_json(data):
flat = [] #list of flat dictionaries
def flatten(y):
out = {}

def flatten2(x, name=''):
if type(x) is dict:
for a in x:
if a == "name":
flatten2(x["value"], name + x[a] + '_')
else:
flatten2(x[a], name + a + '_')
elif type(x) is list:
for a in x:
flatten2(a, name + '_')
else:
out[name[:-1]] = x

flatten2(y)
return out

#Loop needed to flatten multiple objects
for i in range(len(data)):
flat.append(flatten(data[i]).copy())

return json_normalize(flat)

由于名称-值 if 语句,我知道它不是完全通用的。但是,如果删除创建名称-值字典的豁免,则代码可以与其他嵌入式数组一起使用。

关于python - 嵌套的 json 到 csv - 通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37706351/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com