【问题标题】:Iterating through a JSON file in python 3在 python 3 中遍历 JSON 文件
【发布时间】:2020-07-21 11:43:49
【问题描述】:

目前我正在尝试从包含日期和国家/地区的 json 文件中获取“严格”数据。以下是 json 输出的摘录:

import pandas as pd
import json
from bs4 import BeautifulSoup

# load file
with open("Stringency April 8.txt") as file:
    stringency_data = json.load(file)

stringency_data["data"]

#this gives the output:

{'2020-01-02': {'ABW': {'confirmed': None,`
   'country_code': 'ABW',
   'date_value': '2020-01-02',
   'deaths': None,
   'stringency': 0,
   'stringency_actual': 0},
  'AFG': {'confirmed': 0,
   'country_code': 'AFG',
   'date_value': '2020-01-02',
   'deaths': 0,
   'stringency': 0,
   'stringency_actual': 0},
  'AGO': {'confirmed': None,
   'country_code': 'AGO',
   'date_value': '2020-01-02',
   'deaths': None,
   'stringency': 0,
   'stringency_actual': 0},
  'AUS': {'confirmed': 0,
   'country_code': 'AUS',
   'date_value': '2020-01-02',
   'deaths': 0,
   'stringency': 7.14,
   'stringency_actual': 7.14},
  'AUT': {'confirmed': 0,
   'country_code': 'AUT',
   'date_value': '2020-01-02',
   'deaths': 0,
   'stringency': 0,
   'stringency_actual': 0},.........

到目前为止,这是我的代码(为了这篇文章,我已经缩短了一点):

# create empty list for dates

date_index = []
[date_index.append(date) for date in stringency_data["data"]]



#creates empty lists for countries

Australia = []
Austria = []
...
US = []

# put these lists into a list
countries_lists = [Australia, Austria,...US]

# put country codes into a list
country_codes = ["AUS", "AUT",..."USA"]
# loop through countries

i = 0

for country, code in zip(countries_lists, country_codes):
    while i<=len(date_index):
        country.append(stringency_data["data"][date_index[i]][code]["stringency_actual"])
        i+=1

当我打印“澳大利亚”列表时,我得到了我想要的所有值。但是从奥地利开始的任何国家仍然是一个空列表。

我得到输出 - KeyError:“AUS”。这表明代码检索了整个时间序列,但仅针对第一个国家(澳大利亚)。如何为每个国家/地区代码循环?

【问题讨论】:

  • 我会调试/打印您要表达的列表的内容。尝试打印出 list(stringency_data["data"])。根据上面的代码示例,我看不出 stringency_data 中的“data”键在哪里有意义,但这可能会引导您朝着正确的方向前进,这可能是您想要从每个 stringency_data["data "].值()。你能告诉我们 stringency_data 是在哪里分配的,所以我们可以看到“data”键吗?
  • 还请注意,您可以只分配列表理解的结果,而不是使用 append 对其进行迭代。例如。 myList = [thing.property for thing in myDict["myKey"]] 可能是您最终得到的结果。
  • KeyError: "AUS" 建议在数据中找不到 AUS - 您是否检查过数据以确保 AUS 确实在其中?您可能想要在该块中捕获异常,或者使用.get() 为未找到密钥提供安全默认值。
  • @XGoodrich 我已经编辑了帖子以显示我从哪里获得“数据”键并显示了严格性数据元素。 'data' 基本上是 json 文件的第一个键。
  • @Oliver.R 嘿奥利弗,我已经修改了帖子以表明澳大利亚确实在那里,关于如何进一步解决问题的想法?谢谢:)

标签: python json list loops for-loop


【解决方案1】:

以下是我对您描述/显示的数据的看法:

file data is a dictionary; single known/desired key is "data", value is a dictionary.
--> keys are all date_strings.  Each value is a dictionary.
-----> keys are all country_codes.  Each value is a dictionary.
--------> a key "stringency_actual" is present, and its value is desired.

因此,获取这些数据的简单计划可能如下所示:

1. grab file['data']
2. iterate all keys and values in this dictionary.  (Actually, you may only care about the values.)
3. iterate all keys and values in this dictionary.  Keys are country_codes, which tell you to which list you want to append the stringency_actual value you're about to get.
4. grab this dictionary['stringency_actual'] and append it to the list corresponding to the correct country.
4b. translate the country_code to the country_name, since that's apparently how you would like to store this data for now.

我更改了数据检索,因为数据都是字典,因此它可以通过其键进行自我描述。这样做可以帮助防止我在原始问题和评论中看到的 KeyError 。 (如果没有完整的输入文件或 KeyError 的行号,我认为我们都无法 100% 确定输入中的哪个值导致了该 KeyError。)

可能的答案:

import json

# Input sample data; would actually be retrieved from file.
stringency_data = json.loads("""
{"data": {"2020-01-02": {"ABW": {"confirmed": null,
   "country_code": "ABW",
   "date_value": "2020-01-02",
   "deaths": null,
   "stringency": 0,
   "stringency_actual": 0},
  "AFG": {"confirmed": 0,
   "country_code": "AFG",
   "date_value": "2020-01-02",
   "deaths": 0,
   "stringency": 0,
   "stringency_actual": 0},
  "AGO": {"confirmed": null,
   "country_code": "AGO",
   "date_value": "2020-01-02",
   "deaths": null,
   "stringency": 0,
   "stringency_actual": 0},
  "AUS": {"confirmed": 0,
   "country_code": "AUS",
   "date_value": "2020-01-02",
   "deaths": 0,
   "stringency": 7.14,
   "stringency_actual": 7.14},
  "AUT": {"confirmed": 0,
   "country_code": "AUT",
   "date_value": "2020-01-02",
   "deaths": 0,
   "stringency": 0,
   "stringency_actual": 0}}}
}""")

country_name_by_code = {
    'ABW': 'Aruba',
    'AFG': 'Afghanistan',
    'AUS': 'Australia',
    'AUT': 'Austria',
#    ...
    'USA': 'United States'
}

# Output data we want to create
actual_stringencies_by_country_name = {}


# Helper method to store data we're interested in
def append_country_stringency(country_code, actual_stringency_value):
    if country_code not in country_name_by_code:
        print(f'Unknown country_code value "{country_code}"; ignoring.')
        return

    country_name = country_name_by_code[country_code]

    if country_name not in actual_stringencies_by_country_name:
        actual_stringencies_by_country_name[country_name] = []

    actual_stringencies_by_country_name[country_name].append(actual_stringency_value)


# Walk our input data and store the parts we're looking for
for date_string, data_this_date in stringency_data['data'].items():
    for country_code, country_data in data_this_date.items():
        append_country_stringency(country_code, country_data['stringency_actual'])

print(actual_stringencies_by_country_name)

我的输出:

C:\some_dir>python test.py
Unknown country_code value "AGO"; ignoring.
{'Aruba': [0], 'Afghanistan': [0], 'Australia': [7.14], 'Austria': [0]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-09
    • 2016-02-04
    • 2018-10-06
    • 2018-06-19
    • 2017-02-23
    • 2012-06-07
    • 2011-08-09
    • 1970-01-01
    相关资源
    最近更新 更多