8
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

時系列データの前処理(Python 編)

Last updated at Posted at 2021-02-05

はじめに

Python を使って時系列データの前処理を行った際、使ったコードをつらつらと書き足していく。全く同じことをRでも行っているのでそれを読みたい方はこちら

開発環境

  • python 3.8.5
  • pandas 1.1.3
  • numpy 1.19.2
  • jupyter lab 1.2.6

更新履歴

  • 2021/02/05:初投稿。データの読み込みから欠損の確認まで。

参考にした記事

モジュールのインポートとデータの読み込み

データは時系列かつ多変量であるWater Treatment Plantを利用した。

必要なモジュールをimport し、データを読み込む。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("./water-treatment.data", header=None, index_col=0)
df

wtd_01.png

後々のために日付のカラムをindexとして指定している。

データの結合(複数ある場合)

データのcsvファイルが複数ある場合は、それを結合し一つのDataFrameとして扱いたい。各列の要素が同じであることをチェックしたら、

df = pd.concat([df0, df1, df2])

で結合すればよい。#今回の場合は1ファイルなので不要。

index の datetime化と時刻でのソート

index に時刻がD-日付/月/年という形式で入っているので、それをdatetime型に直す。pandas では、to_datetimeという便利な関数があるので、それを使用する。

df.index = pd.to_datetime(df.index, format='D-%d/%m/%y') #datetimeに変換
df = df.sort_index() #時刻でソートする
df

wtd_02.png

データの重複の確認

各列のデータに対して重複が無いかをチェックする。列を直接比較する方法は難しそうなので、一旦転置し重複行を探して削除し、再度転置して戻すという方法を取る。

df.T.duplicated() #重複の確認

今回のデータの場合全てFalseなので重複は無し。重複があった場合は、

df = df.T.drop_duplicates().T

で重複を削除できる。(参考記事1)

因みに要素ではなく列名で重複を確認する場合は以下に示す。

print(df.columns.duplicated()) #重複があればnp.array にTrueが入る
df = df.loc[:,~df.columns.duplicated()] #重複していない項目だけでdfを再構成

データのサンプル間隔を調べる

よくよくデータを見てみると等サンプルのデータではなさそうなので、サンプリング間隔のヒストグラムを作る。日付の配列df.indexを一つずらした配列を作り順次引き算していくことでデータのサンプル間隔を調べる。

flag = 0 #最初の値を回避する用
dt_day = [] #サンプル間隔を入れる配列

for now, pre in zip(df.index, np.roll(df.index, 1)): 
    if flag == 0:
        flag = 1
        continue
    _tmp = ((now - pre).total_seconds())/(60*60*24) #サンプル間隔を日に変換
    dt_day.append(_tmp)

plt.hist(dt_day, bins=range(0,33))
plt.ylabel("Count")
plt.xlabel("Sample interval [days]")
plt.show()

wt_hist.png

見難いので対数で取ったヒストグラムも作成する。

plt.hist(dt_day, bins=range(0,33), log=True) #y軸をlogにする。
plt.ylabel("Count")
plt.xlabel("Sample interval [days]")
plt.show()

wt_hist_log.png

ほとんどが一日間のサンプリングデータだが1/5程度は二日間、ごくまれに三日間、1データだけ一か月くらい(三十二日間)データが飛んでいる箇所があるよう。

これを「等サンプリングに直す」のは次回。

データの欠損の確認

このデータは欠損を含んでいる(欠損は?で表されている。)ので、その可視化を行う。列ごとに欠損の数を数え、その割合を棒グラフにする。

df = df.replace("?", np.nan) #?をnp.nanに変換
nan_count = df.isnull().sum() #NaNの数を数える
nan_per = nan_count/len(df)*100

plt.bar(df.columns, nan_per)
plt.ylabel("Percentage of NaNs [%]")
plt.xlabel("Columns")
plt.show()

wt_bar2.png

ほとんどのデータは10%以下、多くても12%程度の欠損であることが分かった。
欠損をどう埋めるかは次回。

おわりに

以上、データの下準備とちょっとした分析を行った結果を示した。もし加えて何かをした場合は記事に追記していきたい。

8
19
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
8
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?