我有一个要从API下载的JSON文件。 目前,我已经能够将其导出为JSON,并可以通过Excel Power Query准确地解析数据。
将数据除以Campaign IDS(在这种情况下只有两个),然后在所选期间的每一天中,有几个相关的不同指标。 例如,这些是几行(不完整的)行供您查看其工作原理。
campaignId metadata.id metrics.impressions metrics.clicks
s00821idk 2019-05-19 12000293121 100
s00821idk 2019-05-18 12300223151 103
我曾尝试使用Excel来解析此数据,这违背了使用API的目的。 由于我是从Python导出的,因此请通过Excel运行它,然后将其放在Google表格中。
我想用Python进行所有转换,以便可以使用Google Sheets API并将其放在其中。
在下面的链接中,我提供了导出的JSON文件。 file
如果能以这种方式帮助我构造数据,将非常感谢。 非常感谢。
答案 0 :(得分:0)
如前所述,您需要完全展平多个嵌套值,然后迭代以获得所需的内容。可以这样做,但是它很大(每个广告系列ID超过24,000列),因此需要2分钟来遍历您提供的整个内容。
import json
import pandas as pd
import re
with open('C:/data.json') as f:
jsonObj = json.load(f)
def flatten_json(y):
out = {}
def flatten(x, name=''):
if type(x) is dict:
for a in x:
flatten(x[a], name + a + '_')
elif type(x) is list:
i = 0
for a in x:
flatten(a, name + str(i) + '_')
i += 1
else:
out[name[:-1]] = x
flatten(y)
return out
flat = flatten_json(jsonObj)
results = pd.DataFrame()
special_cols = []
columns_list = list(flat.keys())
for item in columns_list:
try:
row_idx = re.findall(r'\_(\d+)\_', item )[0]
except:
special_cols.append(item)
continue
column = re.findall(r'\_\d+\_(.*)', item )[0]
column = column.replace('_', '')
row_idx = int(row_idx)
value = flat[item]
results.loc[row_idx, column] = value
for item in special_cols:
results[item] = flat[item]
results.to_csv('file.csv', index=False)
输出:
print (results)
campaignId ... totalCampaigns
0 0081da282b2dbe8140508074366cac91ba ... 2
1 00c03d801da285767a093d0b4d5188fb34 ... 2
[2 rows x 24533 columns]
答案 1 :(得分:0)
IIUC-以下方法如何?
遍历所有campaignResults
,遍历所有results
,并写出campaignID
,metadata.id
以及(例如)metrics.impressions
和{{1 }}每行:
metrics.clicks
结果:
import json
sep = '\t'
with open(jsonfile) as jsonin, open('j2c.csv', 'w') as f:
j = json.load(jsonin)
f.write(f'campaignId{sep}metadata.id{sep}metrics.impressions{sep}metrics.clicks\n')
for cR in range(j['totalCampaigns']):
for r in range(j['campaignResults'][cR]['totalResults']):
f.write(j['campaignResults'][cR]['campaignId']+ sep)
f.write(j['campaignResults'][cR]['results'][r]['metadata']['id']+ sep)
f.write(str(j['campaignResults'][cR]['results'][r]['metrics']['impressions']) + sep)
f.write(str(j['campaignResults'][cR]['results'][r]['metrics']['clicks']) + '\n')
我仍然不太清楚您要提取的数据是什么-仅具有类似日期的模式的值或仅具有特定日期的值?
除此之外,我还没有真正了解您的json文件的结构,因此我尝试创建一个打印出的树,这可能有助于获得更清晰的视图并更精确地提出问题:
# campaignId metadata.id metrics.impressions metrics.clicks
# 0081da282b2dbe8140508074366cac91ba 2019-05-20 176430.0 59.0
# 0081da282b2dbe8140508074366cac91ba 2019-05-19 169031.0 59.0
# 0081da282b2dbe8140508074366cac91ba 2019-05-18 108777.0 62.0
# 0081da282b2dbe8140508074366cac91ba 2019-05-17 272088.0 60.0
# 0081da282b2dbe8140508074366cac91ba 2019-05-16 198100.0 62.0
# ...
# 00c03d801da285767a093d0b4d5188fb34 2018-01-10 0.0 0.0
# 00c03d801da285767a093d0b4d5188fb34 2018-01-09 0.0 0.0
# 00c03d801da285767a093d0b4d5188fb34 2018-01-08 0.0 0.0
# 00c03d801da285767a093d0b4d5188fb34 2018-01-07 0.0 0.0
# 00c03d801da285767a093d0b4d5188fb34 2018-01-06 0.0 0.0
结果:
with open(file) as f:
j = json.load(f)
def getStructure(dct, ind=''):
indsym = '.\t'
for k, v in dct.items():
if type(v) is list:
print(f'{ind}{k}[{len(v)}]')
getStructure(v[0], ind + indsym)
elif type(v) is dict:
print(f'{ind}{k}')
getStructure(v, ind + indsym)
else:
print(f'{ind}{k}')
getStructure(j)
这里有一个小问题:我认为相似列表元素中并不总是有相同的键:
# campaignResults[2]
# . campaignId
# . results[500]
# . . metadata
# . . . id
# . . . fromDate
# . . . toDate
# . . . lastCappingTime
# . . metrics
# . . . impressions
# . . . clicks
# . . . conversions
# . . . spend
# . . . ecpc
# . . . ctr
# . . . conversionRate
# . . . cpa
# . . . totalValue
# . . . averageValue
# . . . conversionMetrics[6]
# . . . . name
# . . . . conversions
# . . . . conversionRate
# . . . . cpa
# . . . . totalValue
# . . . . averageValue
# . totalResults
# totalCampaigns
因此请注意,上面的j['campaignResults'][0]['results'][0]['metadata'].keys()
# dict_keys(['id', 'fromDate', 'toDate', 'lastCappingTime'])
j['campaignResults'][1]['results'][0]['metadata'].keys()
# dict_keys(['id', 'fromDate', 'toDate'])
函数仅查看列表的第一个元素以获取该列表的结构。