こんにちは、Pythonエンジニア育成推進協会 顧問理事の寺田です。私は試験の問題策定とコミュニティ連携を行う立場です。
前回、公開されたばかりのPython3エンジニア認定データ分析実践試験についてお話しました。その中で、出題範囲となるデータの形についてもお話していますが、中にはなじみがないものもあったかもしれません。そこで何度かに分けて、データの形についてお話していきたいと思います。
今回は時系列データについてお話したいと思います。
Python3エンジニア認定データ分析実践試験の出題範囲について
出題範囲となる書籍の序盤部分に関しては、データ概論やデータの種類という内容になっていますので、主教材を読みこなすことによって、ある一定のレベルで理解しやすい部分です。
次の中盤部分は、この試験の中でも出題割合が多くなる中心的な部分になります。ここでは表形式や、数値データ、データの評価が問われますが、割と一般的な話が多くなると考えています。もちろん、データ分析をやってない人にとっては、初めて聞くような言葉や、知らないことも含まれているかもしれませんので難しいと思うかもしれませんが、 データ分析を学びたいという方にとっては、その流れについては理解できるんじゃないかなというように考えています。
終盤の6章以降では、時系列データの処理やテキスト情報の処理、画像データの処理、グラフデータの処理、地理空間データの処理が入ってきます。これらの各データの処理はそれぞれ専門的な分野のものになりますので、データ分析を長くやっていたとしても、あまりやってないものもある人は結構多いかなと考えています。
ですが、どんなデータが来ても対応できるようにしておくことは、Pythonを使って色々なことをする際に対応しやすい状況にはなります。主教材や実際に自分でコードを書くことによって、それぞれのデータの特徴や狙いを学び、理解を深め、取り扱えるデータの種類を増やしてもらいたいと考えています。
数回ほどに分けて、この終盤部分で出てくる各データの形について簡単に解説していきたいと考えています。
※主教材の書籍名や出題範囲の割合などの詳細は以下URLをご参照下さい。
https://www.pythonic-exam.com/cpda
時系列データの処理
時系列データは時間とともにデータがどんどん増えていくようなものになります。よくあるパターンとしては、アクセスログデータ、売上の推移などで、単位としては時間・分・日単位などです。こういった時間とともにデータが増えていくデータを、集計したり、サマライズしたりすることはよくあると思います。
例えば、売上データを日・月単位で集計してみたり、店舗ごと集計してみたり、時間帯ごとの売上を集計してみたりなどです。ある時間帯の売上データだけをピックアップして何かしらの条件で集計するといったこともあるでしょう。こういった処理をしたいときに利用するのが時系列データです。
時系列データの扱いが得意なのはpandasです。
pandasのデータフレームにデータを格納してあげることで、時系列データの扱いが比較的簡単にできるようになります。pandasでの時系列データの形には、Timedelta型、DateOffset型などがあります。
- Timedelta型
例として、実際の日時を記録するタイムスタンプがわかりやすいかと思います。基本的にはdatetime型というものの中に、Timestampクラスというデータ型があります。
もしデータに文字列で時間のデータが入っているカラムがあったら、それをTimestamp型に変えておくことで、範囲指定などがしやすくなります。
- DateOffset型
例えば週単位や、営業日(月曜日から金曜日)というオフセットの値を作ることができるため、ある日から3営業日後を知りたい、10営業日後を知りたいというようなケースや、今から10営業日以内のデータという範囲を作るときに使えます。
- Period型
Period型を使えば、時間の長さを定義できます。例えば、売上データの月サマリーを作りたいとなった場合、1か月の範囲指定を行います。ただ、1か月というのは、月によって日数が違うため、そのままでは月単位にまとめるのはちょっと面倒くさくなります。ここで、Period型にすると、1か月単位という範囲にまとめることができます。
- Timedelta型
時間差を処理することができます。例えば、1日の差などの指定した期間との差を表現することができます。Python標準のdatetime.timedeltaに近いことができますが、pandasではTimedeltaと記述されます。
これらのデータ型は必要に応じて使っていくことになると思います。
先ほどの売上データの例で言えば、営業日の期間を全部知りたいときなどの方法は、やる必要がないのなら特に必要がないものです。自分で日付を出して計算する方法でももちろん良いとは思いますが、pandasには様々な便利な機能があり、それを使えばより容易に結果を出すことができます。例えば部署別や支店別などはpandasの他の機能と組み合わせることでよりピックアップしやすくなります。
Datetime Indexの活用
ここまで、時系列データを扱うための基本的なデータ型の話をしましたが、これらのデータ型を理解することで、Datetime Indexの話に入ることができます。
Datetime Indexとは、日付型をインデックスにします。つまり、先ほどの例で言うと、Timestamp型を、indexにするようなものです。もちろん、datetimeのままindexしても問題はありません。
これができるようになると、時系列データのまとめ方がより柔軟にいろいろなことができるようになります。例えば、「2024年4月1日以降のデータを全部ください」を、pandasでよく利用されるlocロックアクセッサーを使って簡単に、柔軟にデータを取得することもできます。
また、between_timeという機能もあります。これを使うと、ある日付や期間だけにデータを絞ったり、日付ではなく何時から何時の売上だけ欲しいといった範囲を絞り込んだりすることができ、その結果を使ってサマリーを作る事もできます。
主教材には、これらの説明とサンプルが載っていますので、ここで書かれていることと、主教材を一緒に見て頂けると、より良いのではないかと思います。他の機能も紹介されていますので、ぜひ読んでみてください。
時間間隔を揃えられる「時系列リサンプリング」
続いてリサンプリングの話をします。
リサンプリングメソッドを使い、DateOffsetを渡すことによって、その指定された範囲のものを、新たなデータフレーム(もしくはSeries)にすることができます。これによってサマライズができますし、集計しやすいデータになりますので、次の処理に回しやすくなります。
「dtアクセサ」による日付データ処理
例えば、土曜日のデータが欲しいという場合、pandasを使わない時にはfor文を使ってループさせることで、曜日を一つずつ取り出すというメソッドを使います。
pandasの場合、dtアクセサを利用することで配列の内部に対して順番に適用することができます。そのため、ループしなくとも欲しいデータを取得することができます。
よく使われる形だと、そこにさらに、データフレームの中にdayという新しいカラムに追加して処理を先に進めるように作ることもできます。
dtアクセッサで出来ることには、Pythonの標準にはないものも含まれています。
例えばday_nameですが、これは英語の曜日の名前を直接取ることができます。
補足)
dtアクセッサ以外によく利用されるアクセッサには、strアクセッサがあります。これはstr(文字列型)に関係する メソッドで使えます。
例えば、Seriesに対して、すべて大文字に変換したい場合、[.str.upper()]とすることで、配列に入っている文字列に直接影響させたものを出力させることができます。
「タイムゾーン」
時系列データの最後に紹介されているのが、タイムゾーン情報を含むdatetime型の操作です。ここからはpandasの世界から少し離れて、Pythonの世界に戻りたいと思います。
プログラマーの中で、日本に住んでいるだけならタイムゾーンをあまり気にすることはないと思いますが、アメリカやヨーロッパのプログラマーは、タイムゾーンがあるのが当たり前の生活をしている人は数多くいます。
Pythonにおけるdatetimeにはawareとnaiveという2つのものがあります。
awareはタイムゾーンが入っているdatetimeで、naiveはタイムゾーン情報を持っていないdatetimeです。
これはPython3からこういった仕様になっており、明確にawareなのか、naiveなのかを意識してプログラミングする必要があります。
例えば、2024年9月27日10時00分と言った場合、日本で会話している場合にはこれは日本時間のことであるというのは暗黙的に決まっている状態が多いかと思います。これをより明確にしたい場合には、+9やUTC+9、JST(日本標準時間)という表記を付けます。
これをPythonでは、awareを使うことで明確にします。つまり、2024年9月27日10時は「JST」ですよと宣言することで、UTC時間に置き換える時には-9時間(同日午前1時)だと言っているのと同じことができるようになります。つまり、awareを使えば、例えばアメリカ東海岸時間で2024年9月27日10時としたときの時間差を計算することができます。
つまり、タイムゾーンがないものとタイムゾーンがあるものでは、どこの時間の話をしているのかが分からないため、時間差を調べることはできません。そのため、昨今のPythonにおいては、なるべくawareな時間で扱うようにすることで、明確に管理するという方向になっています。とはいえ、時間データの全てをawareにする必要があるかと言われると、そうでないものも実際には存在します。
そういった場合には、naiveを利用することで、タイムゾーンを持たせない管理をすることができます。
例えば、売り上げデータをExcelで管理していた場合、タイムゾーンは設定されていないnaiveなデータです。ですが、各国に支店があるという企業の場合、データの条件を揃えたいのであれば、それぞれのデータにはタイムゾーンが必要です。そのため、データを整えるタイミングでawareなデータにしてあげる必要があります。そうすることで、適切な時間を把握することができ、切り取るべき範囲を明確にすることができます。
日本で生活していると、なかなかタイムゾーンを意識することはないと思いますが、データ分析をする上では、しっかり、このデータがどういうデータなのか、ちゃんとawareなデータになっているのか、そもそもawareなデータにする必要がないのか、などをきちんと考えて、データを整えましょう。
一度awareなデータで扱ってみると、JSTに戻したり、UTCにしたり、差を計算したりというようなことが明確にできるようになると思います。最初はわかりにくいかもしれませんが、入ってくるデータによって適切な処理を行えるようになっておくと、その先が広がっていくのではないかと思います。
さいごに
今回お話した基本的なことを押さえつつ、自分でデータ作るなどして実際に試してみてください。
それが売り上げデータであれば、作ったデータを使ってグラフ化したり、アクセスログであれば分析をしてエラー率を図ってみたりなど、データの評価にチャレンジしてみてください。
データ分析実践試験では、6章から4問(10%)出題されます。
テキストだけでは難しい部分もあるかと思いますので、実践してみながら、着実に理解を深めていただき、得点につなげて頂ければと思います。