pysparkでFitbitの歩数JSONをパースして、平日と休日の平均歩数を求めてみました。
pysparkでの歩数JSONのパース↓
pythonでの歩数比較↓
www.k-hitorigoto.online
確認環境
import sys print(sys.version) 3.8.6 | packaged by conda-forge | (default, Dec 26 2020, 05:05:16) [GCC 9.3.0] print(spark.version) 3.0.1
コード
文字列だった日付を日付型に変換したのち、月、曜日、平日、休日フラグ列を追加したテーブルを作成。それを集計することで月別、平日・休日別の平均歩数をSQLで集計しました。
from pyspark.sql import SparkSession from pyspark.sql import functions spark = SparkSession \ .builder \ .enableHiveSupport() \ .getOrCreate() df = spark.read.json('/tmp/year_2020.json') # 要素[dateTime,value]を行に分割したカラムを作成 col = functions.explode(functions.col('activities-steps')) # 元のデータ列の横にカラムを追加 df = df.withColumn('lines',col) # 元のデータ列を削除 df = df.drop("activities-steps") # dateTime,valueのデータフレームに変換 df = df.select(functions.col("lines.dateTime").alias("strDateTime"),"lines.value") # strDateTimeをパースして日付型にした列の追加 df = df.withColumn("dateTime", functions.to_timestamp("strDateTime", 'yyyy-MM-dd')) # strDateTimeを削除して、dateTime,valueでDF再作成 df = df.select("dateTime", "value") # dateTimeを基に、曜日列、月列を追加 df = df.withColumn("dayOfWeek", functions.date_format("dateTime", 'E')) # 月はそのままだと文字列扱いなので数値にキャスト df = df.withColumn("month", functions.date_format("dateTime", "M").cast("integer")) # dayOfWeekを基に平日と週末を区別する列を追加 df = df.withColumn("is_weekday", functions.when((functions.col("dayOfWeek") == "Sat") | (functions.col("dayOfWeek") == "Sun"), 0).otherwise(1)) # DFをSQLで操作するため、テーブル登録 df.registerTempTable("steps_2019") # dataframeの表示 df.show() # 月別の平日、休日ごとの歩数平均を集計 # filterを使って集計対象範囲を限定 sql = """ select month ,round(avg(value) filter(where is_weekday = 1), 1)as avg_weekday ,round(avg(value) filter(where is_weekday = 0), 1) as avg_weekend from steps_2019 group by month order by month """ df = spark.sql(sql) # dataframeの表示 df.show()
実行結果例
# 集計元テーブル +-------------------+-----+---------+-----+----------+ | dateTime|value|dayOfWeek|month|is_weekday| +-------------------+-----+---------+-----+----------+ |2020-01-01 00:00:00| 5179| Wed| 1| 1| |2020-01-02 00:00:00| 8387| Thu| 1| 1| |2020-01-03 00:00:00|18740| Fri| 1| 1| |2020-01-04 00:00:00| 7037| Sat| 1| 0| |2020-01-05 00:00:00| 5392| Sun| 1| 0| |2020-01-06 00:00:00| 7081| Mon| 1| 1| |2020-01-07 00:00:00| 7315| Tue| 1| 1| ... # 集計結果テーブル +-----+-----------+-----------+ |month|avg_weekday|avg_weekend| +-----+-----------+-----------+ | 1| 9708.3| 8414.1| | 2| 9396.2| 8909.2| | 3| 9789.9| 7861.6| | 4| 3967.2| 9067.5| ...
2019年、2020年の月別、平日・休日別平均歩数
月 | 2019_平日 | 2019_休日 | 2020_平日 | 2020_休日 |
1 | 6959.2 | 8497.3 | 9708.3 | 8414.1 |
2 | 7528.9 | 9900.4 | 9396.2 | 8909.2 |
3 | 8818.9 | 9082.3 | 9789.9 | 7861.6 |
4 | 8774.3 | 9723.5 | 3967.2 | 9067.5 |
5 | 7829.3 | 8446.4 | 6073.6 | 8210.1 |
6 | 7271.7 | 9727.4 | 5259.0 | 10724.6 |
7 | 7884.3 | 7851.3 | 5517.6 | 8943.5 |
8 | 7979.5 | 8737.2 | 5268.8 | 9373.4 |
9 | 7785.0 | 8893.8 | 5280.5 | 8368.1 |
10 | 7676.4 | 9320.0 | 3804.2 | 9927.1 |
11 | 8309.2 | 9272.8 | 3488.5 | 10715.1 |
12 | 9141.7 | 9605.4 | 3388.7 | 12626.4 |
2019年は平日と休日の平均歩数の差が小さいですが(休日は平日の約10~20%増)、2020年は4月以降休日と平日の差が顕著になってますね。特に、2020年10月以降は平日と休日の差が約3倍にも開いてます。平日の歩数不足を休日の散歩等でカバーしようとした結果が表れていますね...
参考にしました