LoginSignup
4
7

Ruby + PyCall でデータサイエンス100本ノック(構造化データ加工編)をやってみた

Last updated at Posted at 2023-05-14

まだ誰もやってなさそうだったのでやってみました。

オリジナルのリポジトリ The-Japan-DataScientist-Society/100knocks-preprocess をフォークして ruby-pycall ブランチを追加しています。

GitHub でノートブックを閲覧したい場合はこちら:
https://github.com/sonota88/100knocks-preprocess/blob/ruby-pycall/docker/work/answer/ans_preprocess_knock_Ruby_PyCall.ipynb


解答例が複数ある場合など一部TODOにしている箇所がありますが、100問全部動かすことができました(私は Python版からコピペして書き換えただけなので、これは PyCall.rb がすごい! という話です)。

一応筆者について書いておくと、データサイエンスに関しては入門者レベルです。データフレームという概念は一応知ってるとか、Jupyter Notebook を触ったことはあるが日常的に使っているわけではない、という感じの人です。Python, Pandas, NumPy のいずれにも詳しくありません。

ちなみに Ruby + RedAmber 版は @heronshoes さんが作成中とのことです。

動かし方

リポジトリとブランチが違う以外はオリジナルのデータサイエンス100本ノック(構造化データ加工編)の README で書かれている手順と同じです。

git clone --branch ruby-pycall https://github.com/sonota88/100knocks-preprocess.git

cd 100knocks-preprocess
docker compose up -d --build --wait

docker compose up が完了するのを待ってからブラウザで http://127.0.0.1:8888/ を開きます。

左のメニューから /work/answer/ans_preprocess_knock_Ruby_PyCall.ipynb を選択してノートブックを開きます。

image.png

左側に Table of Contents を表示させておくと各問題に移動したいときに便利です。

image.png

メモ

Ruby 向けのカスタマイズ

  • Python 版の Dockerfile をコピー+修正して Ruby 用の Dockerfile-ruby を用意する
  • docker-compose.yml を修正して Dockerfile-ruby に切り替える

やったのはこれだけですね。ここはほとんど手間がかかっていません。

RubyData プロジェクトでメンテナンスされている rubydata/datascience-notebook という Docker イメージがありまして、

これをベースイメージとして使うのがポイントです。自前でカスタマイズする必要がほとんどなく、たいへん助かりました。このイメージは便利なのでどんどん使わせてもらいましょう!(← この記事で一番強調したいのはここ)

Python版の Dockerfile との差分はこんな感じ。

--- Dockerfile  2023-05-06 12:13:18.226946937 +0900
+++ Dockerfile-ruby     2023-05-06 12:13:18.242946463 +0900
@@ -1,5 +1,6 @@
-FROM jupyter/datascience-notebook:python-3.10.8
-#FROM jupyter/datascience-notebook:d53a302fbcd0
+# 2023-02-03
+FROM rubydata/datascience-notebook:24a7f04dfc46
+
 USER root
 ENV DEBCONF_NOWARNINGS yes
 
@@ -29,4 +30,6 @@
     && Rscript -e 'pak::repo_add(CRAN = "RSPM@2022-12-16"); pak::pak(c("DBI", "RPostgreSQL", "themis"))' \
     && rm -rf Pipfile* /tmp/* /var/tmp/*
 
+RUN pip install tabulate
+
 HEALTHCHECK --interval=5s --retries=20 CMD ["curl", "-s", "-S", "-o", "/dev/null", "http://localhost:8888"]

ほぼベースイメージの差し替えだけで済んでいます。

DataFrame#query

Python版の解答例では DataFrame#query を使っている箇所がいくつかあるのですが、pandas.rb ではエラーになります(2023-05-13 時点)。そこで、次のように DataFrame#[] を使う方法で愚直に書き換えました。

# P-004 Python版の解答例1
# df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \
#            .query('customer_id == "CS018205000001" & amount >= 1000')

df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \
    [(df_receipt['customer_id'] == "CS018205000001") & (df_receipt['amount'] >= 1000)]

PyCall.rb + Pandas: DataFrame#query の代わりにS式っぽく書けないか試してみた という別記事で書いたように他の対策もありますが、今回は素朴に DataFrame#[] を使うだけにしました。なるべく素のまま書く方針です。

参考

この記事を読んだ人は(ひょっとしたら)こちらも読んでいます

4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7