欠損値処理#

データを収集する機器の不具合やデータ自体の性質から欠損値(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実践テクニック]

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