Python“らしさ”を支える技術。pandasコアコミッターが大事にするマージの方針

数多いPythonライブラリの中でも、データ解析の用途で大きな存在感を示すのが「pandas」です。そしてこのpandasのコミッターを務めるのが、sinhrksこと堀越真映さん。コミッターが感じるOSSのありよう、そしてPythonらしさを教えてもらいました。

Python“らしさ”を支える技術。pandasコアコミッターが大事にするマージの方針

データサイエンスや機械学習の流行に伴い、業務でPythonが使用されるケースが増えてきました。Pythonが選ばれる理由はさまざまですが、「データサイエンスや機械学習に適したライブラリが数多くある」という特性は、この言語が重宝される理由のひとつでしょう。

たとえば、データ分析のための高速で使いやすいデータ構造を提供するpandas。NumPyやpandasのAPIを利用して並列計算・分散処理を行えるDask。こうした海外で開発が主導されたライブラリが、Pythonの隆盛に貢献してきましたが、日本にもpandas、Daskのコミッターがいるのです。データサイエンティストの堀越真映(ほりこし・まさあき/ 1 @sinhrksさんです。

堀越さんは何をきっかけに、OSSコミッターとなったのでしょうか。そして、彼の考える「データサイエンティストとして成長するために必要な要素」とは? 本稿では、彼のたどった道筋をふり返っていただきました。

キャリアのスタートは、エンジニアでもデータサイエンティストでもなかった

──堀越さんは、やはりデータ分析に関連した業務からキャリアをスタートしたのでしょうか?

堀越 いえ、実はキャリアの始まりはエンジニアでもデータサイエンティストでもありませんでした。大学が情報系なので、学生時代にプログラミング言語に触れてはいたものの、新卒入社した会社で配属されたのは海外向けの技術サポートや技術営業などを担当する事業部でした。最初はプログラムを書く仕事をメインではやってはいなかったですね。

──そこから、データ分析に携わるようになったのはどうしてですか?

堀越 自分の担当業務を改善するためにデータを見始めたのが、データサイエンティストとしての出発点です。仕事でプログラムを書くようになったのもそこからでした。

分析業務に携わるならプログラミングのスキルをもっと上げなければダメだと思い、業務外の時間を使って勉強することにしたんです。「何をして勉強すべきだろう」と検討した結果、自分が普段使っているライブラリの中身を解読するのが、スキルを上げるには効率がよいだろうと考えたのです。

2

堀越真映さん:2008年に大学卒業後、メーカー系企業に就職し、サポートエンジニアとしてキャリアをスタート。その後、同企業内でデータ分析の業務に従事するようになる。2016年に外資コンサルティング企業に移籍し、籍はそのままに、現職のARISE analyticsに参加。データ分析技術のスペシャリストとして活躍する他、現在では後進のデータサイエンティストの育成も担当する。

──なるほど。それでPythonライブラリのソースコードを読むようになったわけですね。

堀越 そうです。だから、OSSコミッターになろうとかそういうマインドで始めたわけではありませんでした。でも中身が理解できてくると、徐々に「こんな機能を足してみよう」とか「機能の不整合が目につくから直していこう」と、気になるところがたくさん出るようになって(笑)。そして、徐々にOSS開発にコミットするようになっていきました。

3

▲堀越さんが最初に起票したチケット1は「棒グラフで日付をラベルにした際のフォーマットをより良いものにしたい」という趣旨のIssueだったという。

その変更は、Pythonの流儀に沿っているか?

──pandasの各メソッドは、非常に直感的に使える分かりやすいAPI設計になっています。良質な設計を守るために、コミッターの方々はどのようなことを意識してライブラリをメンテナンスしているのでしょうか?

堀越 メンテナンス以前の根本的な部分をお話すると、pandasの設計が優れているのは、そもそも制作者であるWes McKinney 4 wesmさん、後任のJeff Reback 5 jrebackさんの設計方針が優れていたから、という面が大きいと思います。

それから、「表形式のデータを扱う」という意味では、すでにリレーショナルデータベースという優れた仕組みが存在しています。RDBの仕組みを先行情報として参考にできるので、pandasでは予想外の機能が出てきにくいという側面もあるでしょう。

──いわば、pandasの場合は同じ種類の問題を解いている先駆者がすでにいたわけですね。では、機能を追加する際には、どのような基準で「入れる」「入れない」を取捨選択していくのでしょうか?

堀越 バグ修正は当然ながらマージされます。機能追加の場合はケースバイケースですが、例えば「現状のライブラリのままでは不便なことがある」「いまのAPIの互換性を壊さずに簡単に解決できる方法がある」「それをリーズナブルな手段で実現できている」などの条件を満たしている変更ならば、マージされることが多いです。

それから、メンテナンスする人々の負荷を無駄に増やさないのも大事な方針です。例えば、世界の中でも珍しい、特定の分野だけで使われているファイルフォーマットがあり、「その種類のファイルのI/Oを追加してほしい」というPull Requestが出されたとします。これをマージしたとすれば、将来的に誰もメンテナンスできなくなる可能性が高いですよね。そういうものは取りこまれないことが多いです。

それから先ほどの質問でも少し出ましたが、「処理が直感的にわかりやすいかどうか」はレビューでも重視されています。例を挙げると……

  • 不要なオプションを足さない
  • 単純な関数の直感的な組み合わせで実現できることを、あえて1つの関数にまとめない
  • 1つの処理はなるべく1つのことだけをやる

こうした要素は、コミッターたちが確認している重要な点ですね。

──それらの方針は、pandasのみならず他のライブラリの設計においても重要なことですね。

堀越 また、「便利だけどPythonの思想に合わないからあえて外す」というケースもあります。これは、Rと比較した方がよさそうですね。ちょっと簡単なコードを以下に示します。

Pythonの場合
df[df['month'] == 12].groupby('day')['visitor'].sum()
Rの場合
df %>% filter(month == 12) %>% group_by(day) %>% summarize(sum(visitor))

Pythonで何かの処理を行う場合には、「インスタンス.メソッド」のような書式でメソッドを呼び出します。

一方でRの場合は、ロードされたパッケージの関数はグローバルの領域に置かれているので、関数名をパイプオペレータ%>%で連結する記法がよく使われます。例えば「df(データフレーム)」という変数に表形式のデータが格納されていて、そこから「month列の値が12のもの」を抽出するとしたら、df %>% filter(month == 12)のように記述するイメージです。

Pythonで同様の処理を書くならばdf[df.month == 112]のような形式になります。dfが冗長になってしまうため、長い変数名だと読みにくくなってしまいます。こういったケースにおいて、「よりシンプルに書けるように、条件式中での元データの参照を簡潔にするための特別な名前(X)を追加できないだろうか」という課題提起をするIssueが、pandasで起票されたことがありました。

▲こちらがそのIssue「API: port the magic X from pandas_ply/dplython to pandas proper?」。

確かに便利な場面はありそうですですが、「今ある方法にさらに別のやり方を足すのはPython的ではない」という結論になり、取り下げられることになりました。

──「Pythonのスタイルに沿っているか」は、他のPython系ライブラリでも重視されている方針なのでしょうか?

堀越 Pythonとしての「ふるまいの一貫性」は大事にされていると感じます。

例えば、数値を合計する処理を例に挙げると、Pythonの標準ライブラリにはsum関数があり、pandasにもNumPyにも同様に合計を取る関数があります。それらが「同じようにユーザーの期待する動作をするか」は守るようにしているんです。

他の関数でも、Pythonの標準ライブラリで似た処理をするものがあるならば、それとなるべく同じようなふるまいになるように気をつけていますね。

7

思い出に残る、データ結合処理のバグ修正

エンジニアHubに会員登録すると
続きをお読みいただけます(無料)。
登録ボタンを押すと、利用規約プライバシーポリシーに同意したことになります。
登録のメリット
  • すべての過去記事を読める
  • 過去のウェビナー動画を
    視聴できる
  • 企業やエージェントから
    スカウトが届く