【Pandas】初見データ確認の心得と使えるメソッド!

こんばんは🐼

今日の記事は初見データの確認について。データを扱う以上、どんな分析を行うにも最初はまずデータを眺めることになると思います。

Pandasを使ってcsvファイルやpickleファイルやなんやらからデータフレームに読み込んだはいいものの、初手どうするの!?って人に向けて自分も初心者ながら、参考にしていただきたくこの記事を書きます。

下記のサンプルコードを動作させるには、Pandasライブラリが必要です。

使用するデータ

この記事では、下記のオンライン購買データ(公開データセット)を使用します。下記のコードで23.7MBのファイルを、ネット経由でローカルに保存して使用します。 (実行環境は、Jupyter notebookを想定しています)

import pandas as pd
import requests

url = "http://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx"
response = requests.get(url)

# カレントディレクトリに"onlineRetail.xls"という名前で保存
output = open("onlineRetail.xls", 'wb')
output.write(response.content)
output.close()

# データフレームの作成
transaction = pd.ExcelFile("onlineRetail.xls")
transaction_table = transaction.parse('Online Retail')

データの表示

まずはデータフレームにデータが読み込めているか確認しましょう。head()メソッドを使うとデフォルトでデータフレームの先頭5件を表示できます。

# 先頭5件を表示
transaction_table.head()

f:id:roughnessjoker0815:20190406162901p:plain

引数に数を指定すると、その先頭からn行取り出すことができます。

# 先頭10件を表示
transaction_table.head(10)

f:id:roughnessjoker0815:20190406162905p:plain

末尾を取り出したい場合、tail()メソッドを使用しましょう。

# 末尾5件を表示
transaction_table.tail()

データを読み込んだり、変更を加えたりした時は逐一確認することが基本です。

そのための一番手軽な方法が、head()メソッドやtail()メソッドを使うことです。(先頭や末尾を確認するだけでは不十分な場合は、適切に参照を行う必要があります)

メタ情報の表示

info()メソッドを使用することで、データフレームのメタ情報を取得できます。

transaction_table.info()

f:id:roughnessjoker0815:20190406164043p:plain

この出力には、以下の情報が含まれていることがわかります。

  • インデックスの総数
  • カラム数
  • 各カラムの欠損値を除いたデータ数
  • 各カラムのデータ型
  • データフレームのメモリの使用量

データフレームを読み込んだら、まずは全体の情報から確認して細部を確認するのが基本です。

「そもそもデータは足りているのか?」「データ型はそのままでよいのか?」「欠損はどの程度あるのか?」・・・などは一番最初に確認してしまいましょう。

各カラムの欠損値の数

isnull()メソッドを使用することで、欠損値が含まれているかどうかの真理値を得ることができます。sum()メソッドと組み合わせることで、各カラムの欠損値を取得できます。

transaction_table.isnull().sum()

f:id:roughnessjoker0815:20190406165607p:plain

info()メソッドの結果から計算することもできますが、欠損値の扱いは前処理の中でも特に重要なので、各カラムに欠損がいくつ含まれているか明確に把握しておくのがオススメです。

要約統計量の表示

describe()メソッドを使用することで、各カラムの要約統計量を表示できます。

transaction_table.describe()

f:id:roughnessjoker0815:20190406170116p:plain

デフォルトでは数値型を持つカラムの要約統計量が表示されますが、include='all'オプションを付けることで、全てのカラムの要約統計量を表示することができます。

transaction_table.describe(include='all')

f:id:roughnessjoker0815:20190406170404p:plain

数値型では平均・標準偏差・最小・最大・四分位数といった情報が表示されますが、オブジェクト型(文字列型など)や日付型では、ユニーク数・最頻値とその頻度等の情報が表示されます。

要約統計量で各カラムの「値」のおおまかな特徴が掴めます。

ここでは、CustomerIDが数値として扱われていることに違和感を感じるでしょう。型の変換はastype()メソッドを使うことで行なえます。

astype()メソッドは元のシリーズを書き換えるわけではないので、データフレームに変更を加えたい場合は以下のように代入を行いましょう。

transaction_table['CustomerID'] = transaction_table['CustomerID'].astype('str')

ただしこれでは一つ問題があります。欠損値を表す「NaN」が文字列の"nan"として扱われてしまいます。下記のように欠損値以外をキャストするか、最初から扱いたい型が決まっている場合はデータフレームの読み込み時のオプションで型を指定しましょう。

transaction_table['CustomerID'] = transaction_table[transaction_table['CustomerID'].notnull()]['CustomerID'].astype('str')

データ型の詳細確認

info()メソッドを使うことで、各カラムのデータ型を確認することができましたが、"object"型には複数のデータ型が含まれている可能性があることに注意しましょう。

各カラムのデータ型の詳細情報を確認するのは、以下のような手法で行うことができます。

transaction_table['InvoiceNo'].map(type(str)).value_counts()

f:id:roughnessjoker0815:20190406173656p:plain

InvoiceNoのカラムには、str型とint型が混在していることが分かりました。

先程と同様にキャストを行うことでデータ型を揃えることができますが、このデータフレームではStockCodeやDescriptionも同様なので、データフレーム読み込み時に指定するのが一番楽でしょう。

各カラムのユニークレコードの取得

describe()メソッドの時にも、ユニーク数という言葉が出てきましたがユニークとは「一意な」という意味で、要はカラムに何種類のレコードが存在するかということです。

全体を確認した後は、カラムごとに具体的にどんな値が入っているのかを確認することも重要です。その用途ではunique()メソッドが使用できます。

unique()メソッドを使用することで、重複を除いた一意なレコードを表示できます。

pd.Series(transaction_table['Description'].unique())

f:id:roughnessjoker0815:20190406174952p:plain

一意なレコードと共に出現数まで表示したい場合は、value_counts()を使用します。出現数順にpandas.Series型で結果を返してくれるため、自分はこちらをよく利用します。 f:id:roughnessjoker0815:20190406175458p:plain

まとめ

Pandasを使ったデータの初手確認方法の最低限を紹介しました!勿論これが正解ではありませんし、この後に様々な角度から基礎集計を行う必要があります。

データ確認や基礎集計の技術は、あらゆるデータを扱う場合に必要になってくるので、最初に固めておくと役立つと思います。

特に重要なのは膨大なデータであっても、

  • 欠損値や異常値を見つけられること
  • データにどのような値が入っているのか、どのような型で扱うのか、など全体を掴むこと

なのだと思います。データの外観を掴まないまま基礎集計等を行っても結局は2度手間を踏むか、最悪誤った分析結果を導きだしてしまうかもしれません。

またデータ確認や基礎集計の過程で、データを壊してしまうのも注意しなくてはなりません。特にデータの変更・削除等の処理を行ったなら、データが意図した通りに変更されているか確認しましょう。

分析の経験のある人には当たり前のことだとは思いますが、初心者視点から書かせていただきました。データの確認の習得は、データ分析をスマートに行う第一歩だと思います!

では、おやすみなさい🐼