Pandasのdataframeを使って体重周りの計算をしたお話
目的
- iOSヘルスケアのデータで除脂肪体重がハブられてるのがちょっと面倒くさい
- というのも、除脂肪体重は筋肉の量に関係し、基礎代謝の目安にもなるため
- 除脂肪体重は体脂肪率の逆(下の式1)から求められる
- 基礎代謝は下の式2(または式2補足)で求められる
- 今回はヘルスケアのデータのエクスポートデータではなく、iOSアプリ(QSAccess)から得られたcsvファイルをもとに作成する。
式一覧
- 体重(Kg) W
- Weightの略
- 体脂肪率(%) F
- Fatの略、%値(実際にはcsv取り込み時に小数表記になる)
- 除脂肪体重(Kg) L
- Lean Body Massの略
- 基礎代謝(kcal) B
- base metabolismの略
式1(除脂肪体重を求める)
L = W \times \frac{100 - F}{100}
式2(除脂肪体重から基礎代謝を求める)
B = 370 + 21.6L
式2補足(式2に式1を代入)
B = 370 + (\frac{100 - F}{100} \times 21.6W)
式3 BMIの算出
- 身長 H
- BMIの計算ではm単位。Heightの略
BMI = \frac{W}{H^2}
Pandasとデータフレームの扱い
csvファイルを取り込んで計算するにあたって、Pandasというライブラリ(モジュール)とデータフレームという型に触れることになった。
データフレームとは
(ざっくりとした理解では)表型のデータ種別。今回のようなcsvファイルのような形式がイメージとして近い。
データフレームの列名を変更する
データフレームに対してrenameというメソッドで変更できる。1
ちなみに、以下で'Start'を'日付'と変更しようとしているが、csv取り込み時に基準列に設定した列名は変更できない(らしい)。
# データフレーム上の列名を変更
df = df.rename(columns={'Start':'日付', \
'Body Fat Percentage (%)': '体脂肪率', 'Weight (kg)': '体重'})
参考: pandas.DataFrameの行名・列名の変更 - note.nkmk.me
列の絞り込み
元データには時間帯・期間を表すStart, Finishという列があったが、今回はFinishは不要のため、基準列となっているStart以外のうち、体脂肪率と体重だけに絞り込むことにした。
# データフレームの値列を体脂肪率と体重に絞る
data = df[['体脂肪率', '体重']]
参考: Pandas でデータフレームから特定の行・列を取得する - Python でデータサイエンス
無効データ(0で出力されたレコード)を除外する
計算するにあたって、体脂肪率・体重のどちらかが0だと意味の無いデータになってしまうため、どちらかが0の場合にレコードを除外する必要があった。
以下の、data[data > 0]
が0より大きいデータを有効とする(0以下を無効とする)記述で、無効となった値をdata.dropna()
で除外している。
# 0は欠損値として扱い、そのレコードを削除する
data = data[data > 0]
data = data.dropna()
参考
- 欠損値(外れ値)を除外: pandasでよく使う文法まとめ - @okadate@Qiita
- 特定の条件の値を取得する: Pandas でデータフレームから特定の行・列を取得する - Python でデータサイエンス
計算して出来た値を列として追加する
また、data['列名'] = 値のリスト([])や計算式
という式を書くと、データフレームに列を追加できる。この計算式には列名を指定して、他の列の各行の値をそれぞれ計算に利用することが出来る。
なお、BMIの計算で使用している(height ** 2)
は、height(身長(m))の2乗を示している。(Pythonの構文)
# BMI、除脂肪体重、基礎代謝(Katch-McArdle式:除脂肪体重から算出する式)を求める
data['BMI'] = data['体重'] / (height ** 2)
data['除脂肪体重'] = data['体重'] * (1 - data['体脂肪率'])
data['基礎代謝'] = 370 + (21.6 * data['除脂肪体重'])
参考: Pandas のデータフレームに行や列 (カラム) を追加する - Python でデータサイエンス
あとは順次計算していくだけ
以下にこれまでのコードをまとめたソースコードを示します。
# データフレーム上の列名を変更
df = df.rename(columns={'Start':'日付', \
'Body Fat Percentage (%)': '体脂肪率', 'Weight (kg)': '体重'})
# データフレームの値列を体脂肪率と体重に絞る
data = df[['体脂肪率', '体重']]
# 0は欠損値として扱い、そのレコードを削除する
data = data[data > 0]
data = data.dropna()
# BMI、除脂肪体重、基礎代謝(Katch-McArdle式:除脂肪体重から算出する式)を求める
data['BMI'] = data['体重'] / (height ** 2)
data['除脂肪体重'] = data['体重'] * (1 - data['体脂肪率'])
data['基礎代謝'] = 370 + (21.6 * data['除脂肪体重'])
あとは
出来たcsvデータをExcelに取り込んで一部をグラフ化したり。結局、体重と比べやすい除脂肪体重を見れば十分だったりします。
その他参考(csv読み込み等)
-
{'key': 'value'}で表されるのは辞書型のデータ ↩