統計解析では、JSONデータを扱うことがよくありますが、複雑な構造の場合、必要なデータを取得するのに苦労します。
例を示します。
愛知県のCOVID-18のJSONデータをPythonのPandasで読み込みます。求めるデータがセルにまとめて置かれているので、リストのアイテムにアクセスできません。
import json
import pandas as pd
import matplotlib.pyplot as plt
df0 = pd.read_json('data/aichi.json')
print(df0)
## lastUpdate ... inspection_persons_summary
## date 2021/02/10 13:27 ... 2021/02/10 13:27
## data 2021/02/10 13:27 ... [{'日付': '2020/03/23', '検査人数': 74, '陽性者数': '', ...
##
## [2 rows x 5 columns]
JSONを読みこんでRStudioのEnvironmentで表示します。
辞書とリストがツリー状に配置されていることがわかります。求めるデータは点線で囲まれた部分です。
JSONをPythonで扱うには、まず、辞書に変換します。階層構造は辞書とリストで表現されます。
リストと辞書のそれぞれの特徴は次です。
mylist = [1, 'a', 'b', {'菅義偉': 70}, ['二階', 82], ['gender', 'male']]
print(mylist)
## [1, 'a', 'b', {'菅義偉': 70}, ['二階', 82], ['gender', 'male']]
[ ]ではさみます。
辞書({'菅義偉': 70})やリストをitemにすることができます。
インデクス(最初のitemを0とする連番)によって値にアクセスします。例えば、mylist[2]は、{‘菅義偉’: 70}です。
mydic = {'a':[1, 'b'], 'male': {'菅義偉': 70, '二階': 82}}
print(mydic)
## {'a': [1, 'b'], 'male': {'菅義偉': 70, '二階': 82}}
{ }ではさみます。
{キー: 値}の形をとり、リストや辞書を値にすることができます。
インデクスはありません。キーを指定して値にアクセスします。例えば、mydic[‘a’]は、[1, ‘b’]です。
コーディネートした上着とパンツの箱を特定するスクリプトです。
キーが服、値が箱番号の辞書(boxes)を作成します。
キーがコーディネイト例、値が衣服のリストの辞書(collections)を作成します。
collectionsのキー(‘formal’)の値(‘jacket1’, ‘pants1’)を順にboxesのキーとして取得した値のリストを表示します。
# create a dictionary
boxes = {'jacket1': 'box1', 'jacket2': 'box2', 'pants1': 'box3', 'pants2': 'box4'}
# create coordinated collections
collections = {'formal':['jacket1', 'pants1'], 'casual':['jackat2', 'pants2']}
# show the boxes for formal
[boxes[item] for item in collections['formal']]
## ['box1', 'box3']
Iのデータのdata>main_summary_history>dataにあるデータはじめの10件を表示します。
全体のdataとその中のmain_summary_historyは辞書です。この中のdataはリストで、その中に辞書が置かれています。
辞書のvaluesはkeysで指定する、リストのitemsはインデクス(番号)で指定するので、データの初めの10行を表示するこコードは次です。
# show the data
num =range(0, 10)
for i in num:
print(data['main_summary_history']['data'][i]['更新日時'], data['main_summary_history']['data'][i]['陽性患者数'])
## 2020/03/16 22:00 123
## 2020/03/25 22:00 148
## 2020/03/26 22:00 154
## 2020/03/27 22:00 157
## 2020/03/28 18:00 164
## 2020/03/29 22:00 164
## 2020/03/30 20:00 170
## 2020/03/31 21:00 178
## 2020/04/01 20:00 178
## 2020/04/02 21:00 190
main_summary_historyのdataのキー’更新日時’とキー’ 陽性患者数’の値からデータ・フレームを作成します。
# count the number of elements
numbers = range (0, len(data['main_summary_history']['data']))
# get the dates and counts of the congirmed with list comprehensions
ls_date = [data['main_summary_history']['data'][n]['更新日時'] for n in numbers]
ls_confirmed = [data['main_summary_history']['data'][n]['陽性患者数'] for n in numbers]
# create a data frame
df1 = pd.DataFrame(list(zip(ls_date, ls_confirmed)), columns =['date', 'confirmed'])
# convert the dates to datetime
df1['date'] = pd.to_datetime(df1['date'])
df1.head()
## date confirmed
## 0 2020-03-16 22:00:00 123
## 1 2020-03-25 22:00:00 148
## 2 2020-03-26 22:00:00 154
## 3 2020-03-27 22:00:00 157
## 4 2020-03-28 18:00:00 164
求めるデータはリストです。
リストの中に辞書がある次の形の場合は、DataFrame()で一括してデータ・フレームに変換することができます。
[{key1: value1, key2: value2, key3: value3}]
df2 = pd.DataFrame(data['main_summary_history']['data'])
df2.head()
## 更新日時 検査実施人数 陽性患者数 入院 軽症無症状 中等症 重症 ... 調整 退院 死亡 入院中 軽症中等症 転院 備考
## 0 2020/03/16 22:00 1297 123 7 ... 11 14 97 90 1
## 1 2020/03/25 22:00 2285 148 8 ... 29 17 102 94 0
## 2 2020/03/26 22:00 2406 154 9 ... 36 18 100 91 0
## 3 2020/03/27 22:00 2535 157 8 ... 42 19 96 88 0
## 4 2020/03/28 18:00 2661 164 9 ... 51 19 94 85 0
##
## [5 rows x 17 columns]