pandasでサンプルのデータセットを使う4個の方法をまとめた

pandasを使っていて、ある関数の挙動を確認するのに、ちょろっとお試しのデータセットがあれば良いなぁ、と思うことがある。

俺も以前の記事で、pandasの使い方を説明するときに、自作のデータセットを使って書いていた。
[pandas]特定の条件を満たす行を削除する - 子供の落書き帳 Renaissance
これくらい簡単なものならばまだ良いけど、いちいちデータセットを自分で作るより、すぐに読み込んで使えれば楽である。
ありがちなのはiris(アヤメ)のデータだけど、その手のサンプルのデータセットを簡単に読み込む方法はあるのだろうか?

f:id:soratokimitonoaidani:20190327225337p:plain

pandas自体にサンプルデータセットの機能は無い

pandas単体では、そのような方法は無い。……たぶん。
pandasの公式チュートリアルのページ
Getting started — pandas 1.0.3 documentation
を見ても、自分で入力した、手作りの(?)データセットを使って説明している。

ということで、他のライブラリを活用してデータセットを読み込む方法を調べた。
正直に言うと、以下の話は
python - Sample datasets in Pandas - Stack Overflow
dataset - Are there any example data sets for Python? - Stack Overflow
あたりをまとめ直して、自分で追加で調べて、コード書いて検証した、というものなので、
英語読める人は、上記のstackoverflowを見たほうが早いかもしれない。

それぞれの方法について、利用できる主なデータ(俺の主観)を挙げた。

pandas:urlを指定してread_csv

pandas.read_csv — pandas 1.0.3 documentation
read_csv関数は引数としてURLを取ることができる。
したがって、read_csv関数を使えばよい。

# pd.read_csv('https://github.com/mwaskom/seaborn-data/blob/master/iris.csv')
# はエラーになる
data = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
print(data.head())
   sepal_length  sepal_width  petal_length  petal_width species
0           5.1          3.5           1.4          0.2  setosa
1           4.9          3.0           1.4          0.2  setosa
2           4.7          3.2           1.3          0.2  setosa
3           4.6          3.1           1.5          0.2  setosa
4           5.0          3.6           1.4          0.2  setosa

seaborn

seaborn.load_dataset — seaborn 0.10.1 documentation というのが、データをロードする関数だ。

おおもとのデータは
GitHub - mwaskom/seaborn-data: Data repository for seaborn examples
にある。ここには「seabornのドキュメントのためのサンプルなので、ドキュメントにとって不要と判断したらデータセットを変更・削除する可能性もあるよ」と書かれている。

import seaborn as sns

# 利用できるデータセットの一覧を表示
sns.get_dataset_names()
(警告が出たけど省略)
['anscombe',
 'attention',
 'brain_networks',
 'car_crashes',
 'diamonds',
 'dots',
 'exercise',
 'flights',
 'fmri',
 'gammas',
 'iris',
 'mpg',
 'planets',
 'tips',
 'titanic']

GitHubを見ても、どのデータセットがどういうものなのか書いてない……他の文献などを見て判明したのは以下の通り。

titanic.csvもあるが、kaggleのtitanicと大筋は似ているけど細部が違うようだ。(例えば、seabornのtitanicには乗客の氏名がない)

おなじみirisデータをダウンロードしてみよう。

iris = sns.load_dataset('iris')
print(iris.head())
print(type(iris))
   sepal_length  sepal_width  petal_length  petal_width species
0           5.1          3.5           1.4          0.2  setosa
1           4.9          3.0           1.4          0.2  setosa
2           4.7          3.2           1.3          0.2  setosa
3           4.6          3.1           1.5          0.2  setosa
4           5.0          3.6           1.4          0.2  setosa
<class 'pandas.core.frame.DataFrame'>

関数の返り値が既にDataFrame型なので、変換の必要はない。

scikit-learn

scikit-learnでロードできるデータセットは、
7. Dataset loading utilities — scikit-learn 0.22.2 documentation
サンプル用のデータセット(Toy datasets)の他にも、

などがあるが、今回は省略。詳細は上記リンクを参照してほしい。

Toy datasetsにリストアップされてるのは全7種類である。本などでは、
iris(アヤメのデータ)
boston(ボストンの住宅価格のデータ)
あたりを見かける事が多い気がする。

from sklearn import datasets

iris = datasets.load_iris()
sample_data = iris['data']
print(pd.DataFrame(sample_data).head())
     0    1    2    3
0  5.1  3.5  1.4  0.2
1  4.9  3.0  1.4  0.2
2  4.7  3.2  1.3  0.2
3  4.6  3.1  1.5  0.2
4  5.0  3.6  1.4  0.2

このままでは列の名前が分からないので、DataFrame作成時にcolumnで指定する。

print(pd.DataFrame(sample_data,
            columns=iris['feature_names']).head())
   sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)
0                5.1               3.5                1.4               0.2
1                4.9               3.0                1.4               0.2
2                4.7               3.2                1.3               0.2
3                4.6               3.1                1.5               0.2
4                5.0               3.6                1.4               0.2

正解ラベルはtargetの中に入っている。

print(pd.Series(iris['target']).head())
print(iris['target_names'])
0    0
1    0
2    0
3    0
4    0
dtype: int32
['setosa' 'versicolor' 'virginica']

statsmodels経由でR datasets

「statsmodelsは、多くの統計モデルの最適化の実行や、統計検定の実施、データの探索や可視化を行うためのPythonのライブラリです」(Pythonによるデータ分析入門 13.3)
……らしいが、今回は統計分析はしない。
専らデータのロード用としてstatsmodelsを使う。statsmodelsを使えばRのパッケージに付属するデータをロードできる。
The Datasets Package — statsmodels

statsmodels.datasets.get_rdataset関数を使うと、
http://vincentarelbundock.github.io/Rdatasets/ の中にあるデータをロードできる。

おなじみのirisは、 パッケージ名'datasets'、データセット名'iris'なので、以下のようになる。

import statsmodels.api as sm
iris = sm.datasets.get_rdataset("iris", "datasets")
print(type(iris))
<class 'statsmodels.datasets.utils.Dataset'>

実際のデータは、このdata属性の中に格納されている、と以下に書いてある。 statsmodels.datasets.get_rdataset — statsmodels

print(iris.data.head())
   Sepal.Length  Sepal.Width  Petal.Length  Petal.Width Species
0           5.1          3.5           1.4          0.2  setosa
1           4.9          3.0           1.4          0.2  setosa
2           4.7          3.2           1.3          0.2  setosa
3           4.6          3.1           1.5          0.2  setosa
4           5.0          3.6           1.4          0.2  setosa

というわけでirisをロードできた。……だが、1200個以上のデータセットを使えるところがRdatasets利点だと思うので、iris程度ならわざわざこれを使わなくても良いと思った。

ここまで見てきたけど、同じirisのデータでも、特徴量の名称、正解ラベルが一緒か別か、など、微妙に形式は異なっている。

まとめ

  • pandasでサンプルのデータセットを読み込む方法を調べた
  • pandasのみで読み込む方法は無いので、他のライブラリから呼び出す必要がある
  • ライブラリごとに読み込んだデータの形式は異なるので、ドキュメントなどを参照して処理するとよさそう

以上。それでは。