u++の備忘録

iOS標準アプリ「ヘルスケア」からデータを書き出しcsvに変換

はじめに

本記事では、iOS標準アプリ「ヘルスケア」からデータを書き出し、csvに変換する方法をまとめます。

データの概要

ヘルスケアアプリはiOSに標準で搭載され、日常の歩数などが記録されています。自分に身近なデータなので、分析の仮説も立てやすく、データ分析の題材として便利かと思います。

データの取り出し方

手順は以下の通りです。

  1. ヘルスケアアプリからXMLファイルを書き出す
  2. XMLファイルをcsvファイルに変換する

ヘルスケアアプリからXMLファイルを書き出す

まずはヘルスケアアプリからデータを書き出します。この時点でcsv形式になっているPythonなどで扱いやすいのですが、XMLファイルでしか書き出すことはできません。

f:id:upura:20190203184634p:plain

まずは、カレンダーの画面から右上の「人物アイコン」をクリックします。

f:id:upura:20190203174420p:plain

この画面の下部にある「ヘルスケアデータを書き出す」をクリックすると、いくつかの形式でデータが書き出せるようになります。

f:id:upura:20190203174417p:plain

  • メッセージ
  • Gmail
  • LINE
  • Slack

など

f:id:upura:20190203174440p:plain

例えばSlackに送ると、次のようにzip形式で圧縮されたXMLファイルがメッセージとして投稿されます。

f:id:upura:20190203174434p:plain

zipファイルを展開すると、以下のようになっています。「書き出したデータ.xml」に、歩数などのデータが格納されています。

f:id:upura:20190203174448p:plain

中身をエディタで閲覧すると、以下のような形式になっています。

f:id:upura:20190203174423p:plain

XMLファイルをcsvファイルに変換する

ここでは、Pythonを用いてXMLファイルをcsvファイルに変換します。

import xml.etree.ElementTree as ET

tree = ET.parse('../data/Appleヘルスケア書き出し/書き出したデータ.xml')
root = tree.getroot()

上記の操作で、rootという変数にデータが格納されています。

f:id:upura:20190203191456p:plain

あとは要件に応じてデータを加工するだけです。

例えば歩数データが欲しい場合は、typeが 'HKQuantityTypeIdentifierStepCount' に等しいデータのみを取り出します。

import pandas as pd

datetime = []
counts = []

for child in root:
    data = child.attrib

    try:
        if data['type'] == 'HKQuantityTypeIdentifierStepCount':
            datetime.append(data['startDate'])
            counts.append(data['value'])
    except:
        pass

df = pd.DataFrame({
    'datetime': datetime,
    'stepCount': counts
})

df['stepCount'] = df['stepCount'].astype(int)

一定の日時ごとに、歩数のデータが記録されています。

f:id:upura:20190203191713p:plain

最後に、csv形式で保存しておきました。既にデータ自体は読み込めているので、csv形式でファイルを保存せず、そのまま分析を続けるのも一つの手だと思います。

df.to_csv('../data/input/df.csv', index=False)

分析例

ここでは、分析の一例として、書き出した生データから、私の日次の歩数を可視化してみます。

import pandas as pd

df = pd.read_csv('../data/input/df.csv', index_col='datetime')
df.index = pd.to_datetime(df.index, utc=True)
df['datetimeja'] = df.index.tz_convert('Asia/Tokyo')

データは、日付+時刻の形式で格納されています。ただし世界標準時で格納されているため、東京の時刻に変更しておきます。

upura.hatenablog.com

日次でまとめ上げるため、日付のみを取り出した列を作成しました。その後、その列をkeyにgroupbyすれば、日次の集計が可能です。

df['date'] = df['datetimeja'].dt.date
daySummary = df.groupby(['date']).sum()

f:id:upura:20190203192303p:plain

このDataFrameを折れ線グラフで可視化すると、次のようになりました。

import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(20, 12))
plt.rcParams["font.size"] = 18
plt.ylabel('stepCount')
plt.plot(daySummary)

f:id:upura:20190203192357p:plain

2017年10月ごろと2019年1月ごろに大きく跳ねているのは、それぞれ以下の取り組みが原因ですね。きちんと集計できているようです。

upura.hatenablog.com

upura.hatenablog.com

おわりに

本記事では、iOS標準アプリ「ヘルスケア」からデータを書き出し、csvに変換する方法をまとめました。冒頭でも書いた通り、自分に身近なデータなので、データ分析の題材として扱いやすいかと思っています。