pandashでRedashのAPIが返す結果をPandasのDataFrameとして取得する

今日はRedash Advent Calendar 2017 17日目ですね。

qiita.com

mtomitomi.hatenablog.com

上記の記事ではRedashのAPIとPandasを組み合わせる例が紹介されていますが、私も似たようなことをやっているので、この記事では私が実務で使っている方法についても紹介してみます。

事前準備

Redash Advent Calendarでは定番になりつつある以下のリポジトリを使用して、Redashが利用できるようになっていることを前提にします。

github.com

クエリID1として、以下のクエリを登録しておきました。

SELECT * FROM city WHERE CountryCode = '{{CountryCode}}' ORDER BY Population DESC;

また、RedashユーザーのAPIキーが必要になりますが、その手順については、先程も紹介した記事に記載がありますので、そちらを参照してください。

RedashのAPI

業務でもヘビーにRedashを使っているのですが、Redashの /api/queries を例に取ると、アクセスはブラウザからでなくスクリプトからのアクセスが7割を超えています。

Redashのキラーフィーチャーは各社の導入目的によって異なるものだというのをAdvent Calendarに参加して強く感じていますが、私は以下の特徴についてRedashに大きな魅力を感じています。

  • 様々なデータソースに対応している
  • Webアプリとして提供されるためアプリをインストールする必要がなく、誰でもすぐに使い始められる
  • フォーク機能やクエリパラメータを使用して、エンジニアでなくてもある程度クエリをカスタマイズできる
  • APIが提供されているため、外部スクリプトでクエリ結果を使用した処理が作れる

あえて太字にしましたが、特にAPIが提供されているところが、私たちの生産性を大きく押し上げています。

私の場合、APIがなかったらここまでRedashにどっぷりハマることもなかったでしょう。

さらにRedashのAPI、特にクエリ実行をクエリパラメータつきで実行することができる、RedashDynamicQueryがPythonのモジュールとして使用できるので、Redashの便利な機能を気軽に使うことができます。

github.com

余談ですが、RedashDynamicQueryを見つけるまでは、APIではなくスクレイピングCSVダウンロードしていたこともあります。

RedashとPandas

さて、ここまではRedashとRedashDynamicQueryの紹介でしたが、Pythonでデータを扱うとなると、Pandasも関わりの強いモジュールといえます。

Python Data Analysis Library — pandas: Python Data Analysis Library

先程紹介したAdvent Calendarの記事でも、APIの結果をPandasのDataFrameにしてJupyter Notebookで扱うといった例になっていました。

Pandasはデータ操作の機能が便利なのはもちろんのこと、scikit-learnなどの機械学習ライブラリとの相性もいいので、どんなデータでもDataFrameに持ち込んで、あとはPandasで自由にデータ操作できるのがとても便利です。

私の場合、現時点ではRedashのクエリ結果をJOINすることが必要になった場合、RedashのPythonデータソースは使わずにAPIでクエリ結果を取得し、Pandas上で結合するようにしています。

余談ですが、PandasやDataFrameについて、個人的にはRebuildの以下のエピソードの中で出てきた、「DataFrame is JSON for Data Science」という表現がしっくりきました。

rebuild.fm

とにかくDataFrameにしてしまえばあとはどうにでもなる感じがしています。

pandash を使ってRedashのAPIの結果をPandasのDataFrameにする

では、実際にRedashのクエリ結果をPandasのDataFrameとして取得する例を紹介します。

Pandasだけでもそれほど難しい処理にはなりませんが、私は自作の pandash というモジュールを使っています。

github.com

前フリがかなり長くなりましたが、このモジュールを使ってRedashの結果を取得してみます。

インストール

環境に合わせて virtualenvvenv を使っていただくとして、モジュールはREADMEの通り以下のコマンドでインストールできます。

pandash は今のところPyPIには公開していません。

$ pip install redash-dynamic-query
$ pip install git+https://github.com/ariarijp/pandash

サンプルコード

以下のコードを main.py として保存します。

from redash_dynamic_query import RedashDynamicQuery

from pandash import query_to_df

redash = RedashDynamicQuery(endpoint='http://localhost',
                            apikey='REDASHのユーザーAPIキー',
                            data_source_id=1,
                            max_wait=60)

df = query_to_df(redash, 1, {'CountryCode': 'JPN'})

print(df.head(10)[['District', 'Name', 'Population']])

このコードでは、Redash上のクエリID1をクエリパラメータを指定して実行し、結果を上位10件の都道府県名、都市名、人口を表示しています。

これを実行してみると以下のような結果が表示されます。

$ python main.py
    District                 Name  Population
0   Tokyo-to                Tokyo     7980230
1   Kanagawa  Jokohama [Yokohama]     3339594
2      Osaka                Osaka     2595674
3      Aichi               Nagoya     2154376
4   Hokkaido              Sapporo     1790886
5      Kyoto                Kioto     1461974
6      Hyogo                 Kobe     1425139
7    Fukuoka              Fukuoka     1308379
8   Kanagawa             Kawasaki     1217359
9  Hiroshima            Hiroshima     1119117

とてもシンプルなコードでRedashのクエリ結果をPandasのDataFrameにすることができました。

まとめ

Redashのクエリ結果をPandasのDataFrameとして扱えるようになると、データをPandasの統一されたインターフェースで操作できるため、クエリ結果にひと手間かけたい、別の処理に渡す前の前処理をしたいなど、データ活用の幅が広がると思います。

よろしければRedash活用の際にRedashDynamicQueryやPandasとあわせて、 pandash も検討していただけるとうれしいです。