5
6

More than 3 years have passed since last update.

Garmin fit形式ファイルの解析手順

Last updated at Posted at 2021-07-29

はじめに

Garminなどで計測したデータをフルに活用するには、fitファイルとして出力されたデータを解析する必要があります。hiking時のデータを事例にfit形式ファイルを解析する方法をまとめました。

1. fitparseライブラリをインストールする

!pip install fitparse

import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import os
import fitparse

2. fit形式ファイルを読み込む

fitfile = fitparse.FitFile("./xxxxxx/xxxxxx_ACTIVITY.fit")
fitdata=[]
for record in fitfile.get_messages("record"):
    for data in record:
        if data.units:
            fitdata+=[[data.name, data.value, data.units]]
        else:
            fitdata+=[[data.name, data.value, 'NaN']]

3. ファイルの中身を確認する

df1=pd.DataFrame(fitdata)
df1.columns=['item','value','unit']
df1

表示例

item value unit
0 altitude 328.2 m
1 cadence 0 rpm
2 distance 0.0 m
3 enhanced_altitude 328.2 m
4 enhanced_speed 0.0 m/s
5 fractional_cadence 0.0 rpm
6 heart_rate 92 bpm
7 position_lat None semicircles
8 position_long None semicircles
9 speed 0.0 m/s
10 temperature 30 C
11 timestamp 2021-07-28 06:03:02 NaN
12 unknown_87 0 NaN
13 unknown_88 100 NaN
14 altitude 328.2 m

4. 不要な項目を削除する

df1['item'].value_counts()
temperature           1015
unknown_88            1015
fractional_cadence    1015
altitude              1015
enhanced_speed        1015
heart_rate            1015
cadence               1015
position_lat          1015
distance              1015
timestamp             1015
speed                 1015
unknown_87            1015
position_long         1015
enhanced_altitude     1015
unknown_90             865
Name: item, dtype: int64
drop=[]
drop+=df1[df1['item']=='unknown_90'].index.tolist()
drop+=df1[df1['item']=='unknown_88'].index.tolist()
drop+=df1[df1['item']=='unknown_87'].index.tolist()
drop2=sorted(set(drop))
df2=df1.drop(index=df1.index[drop2]).reset_index(drop=True)

5. 項目名をカラム名にしたテーブルに変換する

items2=df2['item'].unique().tolist()
df3=pd.DataFrame(columns=items2,index=range(len(df2)//len(items2)))
for item in items2:
    df3[item]=df2[df2['item']==item]['value'].tolist()

表示例
qqqq.png

Semicircle単位の緯度、経度を度に直すには、以下の式で変換します。地図上にルート表示する場合などに使用します。

df3['latitude']=df3['position_lat']*(180/2**31)
df3['longitude']=df3['position_long']*(180/2**31)
df4=df3[['timestamp','latitude','longitude','altitude','speed','heart_rate']]

6. グラフ化する

fig=make_subplots(specs=[[{"secondary_y":False}]])
fig.add_trace(go.Scatter(x=df4['timestamp'],y=df4['altitude'],name='Altitude'),secondary_y=False,)
fig.update_layout(autosize=False,width=700,height=500,title_text="Altitude")
fig.update_xaxes(title_text="timestamp")
fig.update_yaxes(title_text="Altitude(m)",secondary_y=False)
fig.show()

newplot (2).png

fig=make_subplots(specs=[[{"secondary_y":False}]])
fig.add_trace(go.Scatter(x=df4['timestamp'],y=df4['speed'],name='speed'),secondary_y=False,)
fig.update_layout(autosize=False,width=700,height=500,title_text="Speed")
fig.update_xaxes(title_text="timestamp")
fig.update_yaxes(title_text="speed",secondary_y=False)
fig.show()

newplot (1).png

fig=make_subplots(specs=[[{"secondary_y":False}]])
fig.add_trace(go.Scatter(x=df4['timestamp'],y=df4['heart_rate'],name='heart_rate'),secondary_y=False,)
fig.update_layout(autosize=False,width=700,height=500,title_text="Heart Rate")
fig.update_xaxes(title_text="timestamp")
fig.update_yaxes(title_text="heart_rate",secondary_y=False)
fig.show()

newplot.png

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6