I.何が問題?

統計解析では、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で表示します。

辞書とリストがツリー状に配置されていることがわかります。求めるデータは点線で囲まれた部分です。

II.リストと辞書

JSONをPythonで扱うには、まず、辞書に変換します。階層構造は辞書とリストで表現されます。

リストと辞書のそれぞれの特徴は次です。

1.リスト

mylist = [1, 'a', 'b', {'菅義偉': 70}, ['二階', 82], ['gender', 'male']]
print(mylist)
## [1, 'a', 'b', {'菅義偉': 70}, ['二階', 82], ['gender', 'male']]
  1. [ ]ではさみます。

  2. 辞書({'菅義偉': 70})やリストをitemにすることができます。

  3. インデクス(最初のitemを0とする連番)によって値にアクセスします。例えば、mylist[2]は、{‘菅義偉’: 70}です。

2.辞書

mydic = {'a':[1, 'b'], 'male': {'菅義偉': 70, '二階': 82}}
print(mydic)
## {'a': [1, 'b'], 'male': {'菅義偉': 70, '二階': 82}}
  1. { }ではさみます。

  2. {キー: 値}の形をとり、リストや辞書を値にすることができます。

  3. インデクスはありません。キーを指定して値にアクセスします。例えば、mydic[‘a’]は、[1, ‘b’]です。

III.辞書の中にリストのあるデータの使用例

コーディネートした上着とパンツの箱を特定するスクリプトです。

  1. キーが服、値が箱番号の辞書(boxes)を作成します。

  2. キーがコーディネイト例、値が衣服のリストの辞書(collections)を作成します。

  3. 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']

IV.辞書をデータ・フレームに変換

1.データの表示

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

2.データ・フレームの作成1

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

3.データ・フレームの作成2

求めるデータはリストです。

リストの中に辞書がある次の形の場合は、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]