欠損値処理#

データを収集する機器の不具合やデータ自体の性質から欠損値(missing value) が生じる場合があります。時系列データの場合は、csvファイルの一部が欠けているような状況です。
線形回帰モデル、決定木、ニューラルネットワークなど、多くのモデルは欠損値があるデータを直接扱えません。また、時系列モデリングにおいては、サンプリング間隔が一定であることを仮定している場合が多く、欠損値のある時刻のデータを除外することもできません。
したがって、データの前処理の段階で欠損値を確認し、何らかの方法で補完する必要があります。

ここでは、簡単な欠損値補完の方法を解説します。

まず、「可視化/データの準備」と同様に欠損値を含むデータを読み込みます。

import warnings

warnings.simplefilter("ignore")
import pandas
import numpy as np

fname = "../data/2020413_raw.csv"
df = pandas.read_csv(fname, index_col=0, parse_dates=True, encoding="shift-jis")

次のような、9列目・19列目のデータの型が混在しているためうまく読み込めないというWarning が生じます(ここではwarnings.simplefilter('ignore') のため実行結果には表示されていません)。

DtypeWarning: Columns (9, 19) have mixed types. Specify dtype option on import or set low_memory=False. interactivity=interactivity, compiler=compiler, result=result)

実際に型を確認してみます。

# object型になっている。数値データなのでfloat型であってほしい。
print("9列目のデータ型: {}".format(df.dtypes[8]))
print("19列目のデータ型: {}".format(df.dtypes[18]))
9列目のデータ型: object
19列目のデータ型: object

生のcsvファイルを見てみるといくつかの行に None と書かれた文字列( str )が入り込んでしまっているので、これを除去してfloatにします。  欠損値の処理方法にはいくつか方法がありますが、今回は直前の値で埋めてしまいましょう.

※下記コードを用いるとカテゴリカルな文字データ(意味のあるかもしれないデータ)も消去してしまうので注意

# 関数群の定義
def my_typecheck(x):
    """
    数値に変換できるかできないかを判定する関数
    :param x:
    :return: 変換後のxの型
    """
    try:
        x = float(x)
    except:
        x = x
    return type(x)


def drop_str(df, method="ffill"):
    """
    strを落として補完する関数
    :param df: pandas.Dataframe
    :param method: 補完方法, `ffill`で直前の値で穴埋め
    :return: 補完後のDataframe
    """
    df = df.mask(
        df.applymap(my_typecheck) == str, np.nan
    )  # 型チェック後、strになるものはnp.nanで置き換え
    df = df.fillna(method=method).astype(float)  # np.nanを補完
    return df


# 上で定義した関数で処理を実行
df = drop_str(df)

# 9列目・19列目がfloatに変換されていることを確認
print("9列目のデータ型: {}".format(df.dtypes[8]))
print("19列目のデータ型: {}".format(df.dtypes[18]))
9列目のデータ型: float64
19列目のデータ型: float64

小括#

以上で、最低限のデータの読み込み+加工が終了しました。
次からはこの読み込んだ pandas.Dataframe を用いて、可視化や分析を行っていきます。

参考文献.#

  • 本橋智光. 前処理大全[データ分析のためのSQL/R/Python実践テクニック]

その他の欠損値補完の方法#