2023-06-03に投稿

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

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

github.com/sonota88/100knocks-preprocess/tree/ruby-pycall

オリジナルのリポジトリ 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 のいずれにも詳しくありません。

:::note

ちなみに 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

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

image

メモ

Ruby 向けのカスタマイズ

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

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

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

github.com/RubyData/docker-stacks

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

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#[] を使うだけにしました。なるべく素のまま書く方針です。

参考

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

Originally published at qiita.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

sonota486

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント