Python pandas テストの書き方についてメモ

はじめに

pandasやnumpyとかを使ってデータ分析のようなことをしてると、実行結果が数値だったりしてバグに気づきづらい。結果がおかしいことに気づかないまま論文を書いてしまうのは怖いのでユニットテストを書いておく。

普段、Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理を読みながら勉強してたんだけどこの本にはテストについて書かれていなかったのでネットで調べてみた。(この辺の内容について書かれた記事が少ない気がしたんだけど、この分野ではあんまりテスト書かれてないのかな?)

Pandasのデータ構造

pandasでは以下の様な便利なデータ構造が提供されている。

  • Series

    1次元配列のようなオブジェクト

  • DataFrame

    テーブル形式のデータ構造。

  • Panel

    3次元のデータフレームに相当するデータ構造。

Assertion method

pandas.util.testingの中に色んなAssertion methodが用意されてる。 上に示したpandasが提供する特殊なデータ構造は以下のメソッドで比較する事ができる。

  • assert_series_equal
  • assert_frame_equal
  • assert_panel_equal

これらのメソッドは第一引数と第ニ引数で与えられたオブジェクトを比較する。 unittestモジュールのassertion methodと同じようにactual_objectを第一引数、expected_objectを第二引数で渡してやればいいと思う。

使ってみる

簡単なものならDataFrameを適当に作って比較してもいいと思うんだけど、実際のデータを使ってテストしたい時もあるので、以下の様な感じでcsvファイルから読み込んで比較する。

import pandas as pd
from pandas.util.testing import assert_frame_equal
from unittest import TestCase

class PandasTestExample(TestCase):
    def test_sample_method(self):
        expected_df = pd.read_csv(expected_data_filepath)
        actual_df = sample_method(input_filepath)
        assert_frame_equal(actual_df, expected_df)

テストに使用するデータの作成について

上の例のように実際に使うデータを用いてテストしたい場合、expectedとなるデータを準備しなければならない。

今のところこういう流れでテストを書いている

  1. IPython Notebookを起動して入力データをcsvからインポート. pandas.read_csv(filepath)
  2. こまめにデータの状態を確認しながら、データを加工していく(今から実装したい処理を書いていく).
  3. 上手く動いたらcsvファイルに出力. pandas.to_csv(filepath, index=False)
  4. 出力したデータを使ってユニットテストを書く。
  5. 実装(コードを書き上げる)

実装する前に、IPython Notebook上で一度実装をしているので、ある意味二度手間になっている。但し、IPython Notebook上だと変数名を入力するだけで簡単にデータの中身を確認できるので実装を考えるのがすごい楽。

これよりももっと効率の良い手順があるかもしれないけど、今のところこれが一番しっくりきているので他の方法が思いつくまでこれで実装を続けてみる。

参考

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理