学習方法

Pandas の初期段階での学習方法について思いつくままに記す。なお、コンソールは基本的には IPython を利用する前提だ。プロットなどでは Jupyter Notebook を利用するのが自然かも知れない。

IPython のプロファイルを仕込む

Pandas を学習するときには次のコードを毎回コンソールに打ち込むことになる:

import pandas as pd
import numpy as np

この手間を省略するために、IPython のプロファイル機能を活用する。

bash$ PANDAS_PROFILE_NAME=pandas
bash$ ipython profile create $PANDAS_PROFILE_NAME
bash$ cd $(ipython locate profile $PANDAS_PROFILE_NAME)/startup
bash$ cat common_import.py <<EOF
import pandas as pd
import numpy as np
EOF

他にも、ダミー DataFrame オブジェクトを生成するコードを置くのもよいだろう。

そして IPython セッションを開始するときには次のようにするのだ:

bash$ ipython --profile $PANDAS_PROFILE_NAME

基本ドキュメントを精読する

初学者は Pandas 公式文書の次の二点にまず目を通すことになる。ここに書かれているコードを可能な限り IPython などで試すことで Pandas の本質的な機能を体得することになる。

  • Getting Started の Getting started tutorials

  • User Guide の 10 minutes to pandas

Getting started tutorials ノート

このチュートリアルを実施する際にデモ CSV ファイルが必要だ。普通に読んでいればいずれのファイルもダウンロードできるので問題ないが、オフラインで作業するときにはあらかじめダウンロードしておく。

CSV ファイルから DataFrame オブジェクトを生成するコードを上述のスクリプトに含めておくといい。

titanic = pd.read_csv("path/to/titanic.csv")
air_quality_short = pd.read_csv("path/to/air_quality_no2.csv", index_col=0, parse_dates=True)
air_quality_long = pd.read_csv("/path/to/air_quality_no2_long.csv", parse_dates=True)

要点が各章の終わりにまとめられているので、内容を習得したか確認する。

  • 基礎的概念

    • Pandas のパッケージ要素を利用するには import pandas as pd とする(別名定義はタイプ量節約のため)。

    • クラス DataFrame は二次元の表を表す。これが当ライブラリーの主役のようなものだ。

      • このオブジェクトの生成方法はいろいろある。ここでは dict オブジェクトから直接生成している。

    • DataFrame の列のそれぞれは Series というものだ。

      • DataFrame オブジェクトに対して角括弧 [] を作用させると Series オブジェクトとして列を参照する。

    • Pandas プログラミングでは DataFrame または Series に対してメソッドを呼び出すことで何かをする。

      • ここでの例は .max().describe() にとどめてある。

  • I/O について

    • read_ から始まる名前の関数がファイルからの入力機能だ(アンダースコアのあとにファイルフォーマットを表す名前が付く)。

      • GitHub のリポジトリーから titanic.csv をダウンロードして関数 read_csv() を必ず試すこと。

      • ロード系関数を呼び出した後は、生成された DataFrame オブジェクトの内容を必ず確認すること。

    • 反対に .to_ から始まる名前のメソッドがファイル出力機能だ。

      • メソッド .to_excel() を必ず試すこと。それから関数 read_excel() が動くことを確認すること。これらは MS Excel 形式のファイルを処理するサードパーティー製ライブラリーが何かしらインストール済みでないと動作しないだろう。

    • オブジェクトをチェックするのにメソッド .head(), .tail(), .info() とプロパティー .dtypes が手軽に使える。

      • プロパティー .dtypes を参照すると各列の型を確認できる。object とあるのは実際は文字列型だと思っていいようだ。

      • メソッド .info() がメモリー使用状況も出力していることに注意。

  • DataFrame の部分集合へのアクセス

    • 角括弧を用いるのが基本的だ。

      • 与えられた DataFrame の任意の列を抽出する方法を習得すること。列の個数にも注意。興味深いことに、角括弧に与えるキーとして list は許されるが tuple は許されない。

      • プロパティー .shapeDataFrameSeries の寸法が得られる。

    • そのような角括弧の内側には、単一の行または列ラベル、行または列ラベルのリスト、ラベルのスライス、条件付き式、またはコロンが入る。

      • 例えばタイタニックデータに対して「35 歳を超える乗客の一覧」を抽出できるようにする。

      • Series.isin() について頭の片隅に入れておく。

    • メソッド .loc[] では行名または列名を用いる。

      • 「35 歳以上の乗客の名前の一覧」を得るのに単なる角括弧では不十分である理由を理解する。

    • メソッド .iloc[] では表における添字を用いる。

    • .loc[] にせよ .iloc[] にせよ、値を代入するのにも用いられる。

  • プロットするには

    • SeriesDataFrames の両方にプロパティー .plot が提供されていて、そこからプロット用メソッド各種を呼び出すことができるようになっている。

      • WSL 環境で学習していて Matplotlib をインポートすると Could not connect to any X display のようなエラーメッセージが出る場合には、いったんセッションを閉じる。それから VcXsrv などの XLaunch を起動しておき、再びコンソールを開く。それから IPython を実行し直す。

        IPython でやるのをいったん止めて VS Code の Jupyter Notebook Extension を利用するのも楽だ。.ipynb ファイルを作成するように VS Code を開くといい。

        bash$ code pandas-plot.ipynb
        

        こちらでプロファイルが使えたら環境を乗り換えるのもいいか。

      • .plot() でもプロットできる。

      • 上述の環境で画面が出ないときには明示的に plt.show() を呼び出す。

      • メンバーデータ .plot に対して dir() を呼び出すとプロットメソッド一覧を得ることを憶えておくといい。アンダースコアから始まらないものが該当する。

        • area

        • bar

        • barh

        • box

        • density

        • hexbin

        • hist

        • kde

        • line

        • pie

        • scatter

        IPython 環境ではタブ補完を利用するのも手軽でよい。

    • 基本的には、各列は異なる要素としてプロットされる。

      • 特定の列だけプロットすることもできる。メソッド .plot()Series にもあることに注意する。

    • Pandas が生成するあらゆるプロットは Matplotlib オブジェクトだ。生成したいプロットをカスタマイズするのに Matplotlib プログラミングの技法を活用できる。

  • 既存の列から新しい列を作成するには

    • 代入による。左辺は df[new_column_name] = ... のような形であり、右辺は何らかの出力だろう。

      • このデモコードのような処理をいくつも実行すると、欠損値の振る舞いを肌感覚で理解できる。

    • 操作は要素ごとになされる。行をループする必要はない。

    • 行名または列名を変えるには rename() を使う。

      • キーワード引数 columns の値は dict か関数ということか。

  • 統計概要を計算するには

    • 集約系の統計は列全体または行全体について計算ができる。

      • 基本的には欠損値は除外して計算される。

      • .mean().median() などの出来合いの統計メソッドで事足りるならそうする。

      • .describe() をもっと細かく指定するならば .agg() を検討する。

    • .groupby() は「分割・適用・結合」パターンの原動力だ。

      • 必要ならデータセットの部分集合を選択し、列名などで .groupby() する。そのあとに統計メソッドを適用すると、指定した列の要素別にグループ分けされて、そのグループごとに集計される。

      • Pandas は「適用・結合」を一括して処理する。

      • 複数列による .groupby() の方法を習得すること。

    • .value_counts() は各列に対して、存在する値それぞれがいくつ含まれるかを勘定するのに具合が良い。

      • SQL で言う SELECT column_name, COUNT(1) FROM table_name GROUPBY column_name に相当する。

  • 表の配置を変えるには

    • .sort_values() は列を整列する。一つでも複数でも整列できる。

      • 基準となる列を指定するにはキーワード引数 by に列名または列名のリストを与える。

      • 昇順・降順を指定するにはキーワード引数 ascending に真偽値を与える。

    • .sort_index() も実装されている。

    • 冷静に考えるとここの .groupby() の挙動がよくわからない。

    • .pivot() は純粋にデータを再構築する一方、.pivot_table() は集約を行う。

      • 反対に、こちらの .pivot() はわかりやすい。

      • .pivot() の結果を即 .plot() できる。この例では変動が激しすぎて何も観察できないとは思うが。

      • .pivot_table() のキーワード引数 aggfunc に注意。

      • .pivot_table() のキーワード引数 marginsTrue を与えると All という要約列が生じる。

    • .pivot() の逆は .melt() だ。「縦長を横長にする操作の逆は、横長を縦長にする」と覚える。

      • .reset_index() で序数によるインデックス列が新たに生成される。

      • .melt() によって列名がインデックス側に移動したように見える。

      • .melt() にキーワード引数各種を指定することで詳細にカスタマイズできる。

  • 複数の表からデータを結合するには

    • 関数 concat() を使うと複数の表を、列ごとにでも行ごとにでも結合することができる。

      • axis=0 を指定すると表を縦に結合する。Pandas では使えるところでは axis=0axis=1 を指定するのでこの例で習得する。

      • 複数の表をこのように結合すると、一般的には元のデータの行を特定できなくなる。それを解決するのにキーワード引数 keys を指定する。この例ではよくわからないが、階層のあるインデックス列が追加的に生じる。

    • 表に対するデータベースにおける merging/joining 操作には関数 merge() を使う。

      • 最初の merge() は SQL で言う LEFT INNER JOIN に相当する。キーワード引数 howon に注意。列名が異なる場合には left_onright_onon の代わりに用いる。

      • Pandas は当然 INNER JOIN も OUTER JOIN も提供している。

  • 時系列データを操作するには

    • 関数 to_datetime() を使えば、まともな日付文字列を日付時間オブジェクトに変換することができる。

      • 最初のデモでは変換の前後で .dtypes をチェックするといい。

      • 以前のデモで見たように、ファイルから読み込むときにキーワード引数 parse_dates で変換したい列を(リストで)指定するのがいい。

      • Timestamp オブジェクトはいろいろと有用であるので、可能な限り変換しておきたい。

    • Pandas の日付時間オブジェクトには時間計算、論理演算、日付に関連するプロパティー .dt が備わっている。

      • 月を抽出するデモでは、.dt.month から得られる列の要素型が int であることに注意。

      • 各曜日の各所における二酸化窒素の例での .groupby() は難しい。

      • プロットの例では、ラベルを設定する処理を .plot() の前に持ってくる必要があった。そうしないと plt.show() を明示的に呼び出すと帰ってこない。

    • DatetimeIndex オブジェクトにはこれらの日付関係のプロパティーがあり、使いやすいスライス操作をサポートする。

      • 特に .index から .year.weekday などにアクセスできる。

    • .resample() は時系列の頻度を変える強力なメソッドだ。

      • .groupby() に似ている。"M""5H" などの対象の頻度を定義する文字列を使ってグループ化する。

      • .resample() の結果に対して .mean().max() などの集計メソッドを呼び出す。

      • .freq にその頻度が保持される。

  • 文字列を操作するには

    • 文字列メソッドは .str から利用可能だ。

      • 例えば列を一つ選択して、それに対して .str.lower() を呼び出す。するとその列名が小文字になった Series オブジェクトが得られる。

      • 同様にして .str.split() などを実行すると文字列からなるリストを要素とする Series が生成する。

      • 演算子 in の代わりに .str.contains() を呼び出す。

      • 演算子 len の代わりに .str.len() を呼び出す。

    • 文字列メソッドは要素ごとに機能し、条件付きインデックスに対して用いられる。

    • メソッド .replace() は与えられた dict オブジェクトに従って値を変換する使い勝手のよいメソッドだ。

      • .str.replace() も別に存在するので注意する。

10 minutes to pandas

とても 10 分で履修できるような分量に収まっていない Pandas の紹介記事だ。上述のチュートリアルと併せて読んでもいいし、チュートリアルだけ読んで次に進んでもいい。

  • Object creation

    • Series オブジェクトの直接生成。

    • DataFrame オブジェクトの直接生成。

      • NumPy の配列オブジェクトとキーワード引数 index, columns を与える方法。

      • 辞書オブジェクトを与える方法。キーが列名で値が Series を生成するデータ。

  • Viewing data

    • .head()

    • .tail()

    • .index

    • .columns

    • .to_numpy() はインデックスや列名を含まない部分を返す。

    • .describe() は統計概要を表示する。

    • .T で行と列を入れ替えた表を得る。NumPy と同じ。

    • .sort_index() で行または列をソートする。ここでキーワード引数 axis を指定する。

      • axis=0 ならば行を入れ替えるようなソート。

      • axis=1 ならば列を入れ替えるようなソート。

    • .sort_values() では基準となる行または列を指定してソートする。キーワード引数 by により基準を指定する。

  • Selection

    • 冒頭で本番用コードでは、最適化されたアクセスメソッド .at, .iat, .loc, .iloc を推奨するとあることに注意。

    • DataFrame オブジェクトに対して角括弧と列名を指定すると Series を参照できる。

    • この角括弧でスライス記法を用いると、対応する行を参照できる。

    • .loc[] にインデックスを指定するとその行を参照できる。

      • .loc[indexes, columns] のような指定方法もできる。

    • .at[index, column] を用いれば効率的にデータ中の一要素を参照できる。

    • .iloc[i], .iloc[i, j], .iloc[i1:i2, j1:j2], などによりゼロ起点の添字で参照する。スライス記法も可。

    • .iat[i] を用いれば効率的にデータ中の一要素を参照できる。

    • Boolean indexing

      • SeriesDataFrame とスカラー値を比較演算子で評価した式を角括弧の中に入れる。各要素ごとに評価の結果が真である部分だけが抽出される。

      • .isin() などのその目的用のメソッドがある。

    • 存在しない列名を角括弧に入れて左辺値とし、値を代入することができる。こうすると新しい列が生じる。

    • 列名だけではなく、上述の角括弧記法すべてが利用可。Boolean index による指定でもよい。

  • Missing data

    • Pandas は基本的には np.nan を欠損値の表現に採用している。欠損値をオペランドにとる演算は np.nan と評価されるのが基本的だ。

    • .reindex() の機能がこれではよくわからない。

    • .dropna() で欠損値を含む行を削除する。

    • .fillna() で欠損値を指定の値で置き換える。

    • 関数 isna()DataFrame からマスクを作成することができる。

  • Operations

    • さっきも言ったように、データ操作において欠損値は除外される。

    • .mean() などの記述統計メソッドの簡単な呼び出し方を習得する。

    • 寸法の異なるデータ同士の操作には明示的な alignment を必要とすることを理解する。

    • .apply() を使えるようになる(操作を関数の形式で渡すといい)。

    • .value_counts() で度数分布を得られることを理解する。

    • 文字列に関する操作を属性 .str を経由して行うことができる。

  • Merge

    • 関数 concat() でどのように表を連結できるのかを理解する。

    • DataFrame は列を追加するのは比較的高速だが、行を追加するのはコピー操作を必要とするため高く付く。

    • 前述のように .merge() で SQL 風の JOIN 操作を実現できる。

  • Grouping

    • グループ化の神髄は「分割・適用・結合」だ。

    • .groupby() して得られるオブジェクトに対してはだいたい集計メソッドを呼び出すことになると憶えておく。

  • Reshaping

    • TODO: ここを読む前に本文のリンク先二箇所を読んでおくこと。

    • メソッド .stack()DataFrame の列側の階層を「圧縮」する。このデモでは列だった A と B がインデックスのいちばん右に移っている。

    • この逆演算が .unstack() だ。デフォルトではいちばん右の(最下層ということ)インデックスを列側に移す。引数は左(最上層)からの序数を指定する。

    • 関数 pivot_table()DataFrame からピボットテーブルを作成することができる。

  • Time series

    • 関数 date_range() を習得する。

    • 時系列を表す Series に対する .resample() 操作を習得する。特に引数の指定方法。

    • .tz_localize() はタイムゾーンが特定されていない時系列に対してそれを局所化する。

    • .tz_convert() はタイムゾーンが指定されている時系列を別のそれの時系列に変換する。

    • .to_period()DatetimeIndex オブジェクトを PeriodIndex オブジェクトに変換する。

    • .to_timestamp()Timestamp からなる DatetimeIndex オブジェクトに、周期の開始点でキャストする。

    • .asfreq() は時系列を指定の周期に変換する。

  • Categoricals

    • まず categorical の概念を理解する。

    • .astype("category") という操作により単純な型から categorical に変換できる。

    • Series に対して .cat.categories に取り得る値の集合を設定することができる。このような列をソートすると、値の順序関係はその設定時のリストの格納順序に従う。

    • このような列を .groupby() すると、含まれていない要素についても常に表示する。

  • Plotting

    • Matplotlib が裏で動いていることは学習した。

    • .plot() でデフォルトのプロットを描画する。これはすべての列をプロットする。

  • Getting data in/out

    • CSV ファイルの読み書きに対応していることは学んだ。

    • HDF5 Store という何かの読み書きもサポートしている。

    • MS Excel ファイルの読み書きも可能。別途サードパーティー製ライブラリーが必要であることを忘れるな。

  • Gotchas

    • DataFrameSeries を真偽値として扱うようなことは避ける。

関連ノート

Pandas の基礎的依存パッケージおよびオプショナルな依存パッケージに関するノートがいくつかある。