DataFrames and Types with Julia

ki_chi氏:タイトルは英語なんですが、講演自体は日本語でやらせていただきます。「あとで使いまわせると便利かな」と思って、調子に乗って英語にしただけです、すみません(笑)。気になさらずお願いいたします。

「DataFrames and Types with Julia」というタイトルで発表させていただきます。 TwitterIDはこちら、@ki_chiでお願いいたします。

先ほどの方のを拝聴していて、Juliaとの馴れ初めみたいなページも作っとけばよかったなって思ったんですけど。私自身は大学時代に少し数値計算の勉強をすることがありまして。

専門のど真ん中ではない数値計算を少しやっていて、有限要素法をCで全部書いてやるかっていうようなタスクを与えられたとき「こんなんやってられるか!」ってことで。その途中からJuliaを使い始めたのが、Juliaとの馴れ初めだったように覚えています。

それから仕事でも、実務で直接は使ってはいないんですけれども、検証したくてNumPyとか使って行列演算するとコードがごちゃごちゃして鬱陶しいなぁってときに、Juliaを使ってすっきりさせて数値実験してみようとよく使っています。

本題に入ります。今回の発表なんですけど、ちょっと前に私自分自身のブログで書きまして。0.6.2のときの記事なのでちょっと古いんですけれども「DataFramedMeta、JuliaDB、Queryverseをそれぞれ触ってみた」ということで、今回それを少し更新したような内容になっています。

タイトルにもあるように、「DataFrames and Types……」ということで先にデータフレームの話をしたいと思います。

データフレームについて

みなさんこの中で、抜け忍認定されちゃうと怖いんですけれども(笑)。ふだんPythonを使ってデータ分析をされている方、挙手願います。ふだんPythonを使っている方。

(会場挙手)

あ、いますねぇ。けっこういらっしゃいます。

(会場笑)

ではRを使ってデータ分析されてらっしゃる方?

(会場挙手)

いらっしゃいますね。ちょっとPythonより少ないかなって感じですね。両方使ってる方もいらっしゃいましたね。

こういったデータフレームは、そういった方にはお馴染みだと思うんですけれども、エクセルの表みたいなイメージですね。列にタイトルがあって、それぞれデータがぶら下がっているという。

こういうデータ構造を一般的に「データフレーム」って呼ぶことがありまして。このかたちをそのままプログラムで扱えるとすごく嬉しいというのが、データ分析を日々している人の気持ちなんじゃないかなぁと思っております。

いわゆるデータサイエンスと呼ばれるぼやっとした分野の中でも2つ、このどっちかは絶対使っているんじゃないかと思います。もちろんそうじゃない方もいらっしゃるかと思いますけれども。

1つがRとtidyverse。tidyverseはdplyrとかが含まれている複合のパッケージになります。もしくは先ほどたくさん手の上がったPythonと、Pythonの中でデータフレームをきれいに扱えるPandas。

このどっちかの組み合わせをたぶん多くの方が使ってらっしゃるんじゃないかなと思っております。

強力なツールたちと並ぶ方法

この2つの、いわゆるスーパーカップルですねこれらのものすごく強力なツールたちとJuliaが並ぶためにはJuliaに何を組み合わせてどんなパッケージを使ってやったら、さっきのR、Pythonに流れていってしまう人たちを引き止めることができるのか。

抜け忍を選別することができるのか。そういうのを考えてみたいなと思います。

候補としては3つあります。

1つがDataFrames、これはパッケージの名前なんですけれども。DataFramesとDataFramesMetaっていうものの組み合わせとして1つ。

もう1個はJuliaDBというパッケージ。

最後がQueryverseと呼ばれる、tidyverseからネーミングをもじっているような感じになってるんですけど。この3つがたぶんささっと検索すると候補に出てくるんじゃないかなと思います。

DataFrames + DataFramesMeta

1個ずつ簡単に説明させていただければと思います。1つはDataFramesとDataFramesMetaの組み合わせ。

下にGitHubのスター、昨日調べたやつで537のスターが付いていて。たぶんJuliaのテーブル状のフレームワークのパッケージの中では一番人気が高いパッケージなんじゃないかなと思っております。既存のPython、Rを使用している人たちにもわりとわかりやすいようなAPIになっていると。

このDataFramesっていうのが今説明したところで、DataFramesMetaっていうのはDataFramesをより使いやすくわかりやすく操作することができるマクロを提供しているパッケージになります。なのでこの2つを組み合わせて使っているというのが、私がよく見る中で多いのかなと思っております。

すみません、コード見えますかね? 後ろの方。大変申し訳ないんですけれども。ちょっと用意してみました。

どんな感じで使えばいいのかというところです。irisのSepalLengthっていう名前の列の要素だけを取ってきたいなと思ったら、こんな感じで中にSymbolを渡してあげれば、普通にArrayで出てくると。

Arrayの中身、Float64だけじゃないのかなと思われるかもしれませんが、ふだん触っている方はわかると思うんですけれども、データフレームは往々にして欠損値が付き物です。

なのでここで欠損値にも対応できるMissing、確か0.7くらいから入った型だったと思うんですけど。これとのUnionのArrayになって出てきます。

例えば、今のデータの中でSepalLengthが6よりも大きいような行だけを引っ張ってきたいという場合はこういうふうに書きます。

カッコの中でこう書く。たぶんこれはRでもPythonでもこういう書き方はできると思います。

こんな感じで簡単に引っ張ってくることができます。たぶんR、Pythonやってる方はすぐ馴染めるんじゃないかと思います。

先ほどいったマクロを提供しているというDataFramesMetaですね。

Metaは何してるのかと言うと、さっきとほとんど同じような動作なんですけれども。@whereというマクロを用いて、さっきとはちょっと違う文法で書いてますね。これやってることはさっきとぜんぜん同じでして。

今度はPetalLengthという列が1.7以上、さらにSpeciesの列がsetosaになっているものを引っ張ってきたいというので、複数条件で簡単に渡して持ってくることができていて。そこそこ可読性も高いというようなマクロになっています。

グルーピングして計算するというのがよくあると思うんですけれども、そういったときも@byというマクロが用意されてます。これだったらSpeciesごとにSepalLengthがmaxのものを持ってきてほしいというのがマクロになってます。簡単に持ってこれます。

実際にこれをtidyverseのdplyrみたいに全部パイプでつなげるとどうなるかということもできます。

ここの@linqは、C#とかやってる方だとご存じですが、それをパクってきたやつがあるんですけれども。

これを使うとさっきのwhereとかbyとかというのを中でファイルで書けるんですね。Juliaにもパイプがあるのは、たぶんJuliaやってるみなさんはご存じかと思うんですけど。こういうパイプでつなぐことができます。

このパイプ、別にDataFramesの演算子ではなくてJulia一般で存在しますので。たぶん数学とかやってる方でも、積分とか関数を重ねるときに便利なので、僕はよく使ったりしています。

こういうふうに処理を何個もシークエンシャルに重ねていって結果を出すということが、dplyrとかに負けないくらい簡単にできます。

JuliaDB

次いきます。JuliaDBなんですけど、これ名前が紛らわしいんです。DBって言ってはいるんですけど、データベースではないというのは先に言っておきます。

これはJuliaを作った人たちの会社であるJulia Computingの売り物であるJuliaFINっていうプロジェクトがあるんですね。FINはファイナンスのFINです。

その中の1つのパッケージとしてJuliaDBというのがオープンソースで提供されています。特徴としては、インメモリでアウトオブコアで分散のコンピューティングができるぞということを売りにしています。

実際にこれはどうなっているのかというと、さっきのDataFramesに比べると見通しが悪いようなっていうのが、私の印象です。

まず単純にusingで持ってきて、loadtableで持ってきてっていうので。さっきのDataFramesとは違ってtableという名前のものができます。

さっきみたいにSepalLengthが〇〇以下で、Speciesが〇〇でってやるときに、filterという関数を使います。シンボルとそれぞれに適応したい関数のペアと引数に持っているというような仕組みになっています。

ちょっとわかりにくいなと思ってるんですけれども、どんどん先に飛ばしていっちゃいます。

ここでLazyっていう遅延評価のパッケージを使うと、さっきみたいにあたかもパイプでつなげたかのようにシークエンシャルに処理をすることもできます。

filterで条件をかけて、groupbyでグルーピングして、あと新しい列を作ってその中から使うものだけ選んで、最後の書き出すときに名前変えたいなってときはrenameとか使って、最後にsortをかけるみたいにできます。

Queryverse

3つ目です。

Queryverseというのは、tidyverseと同じような感じで、複数のパッケージを1つにまとめた、いわゆるメタパッケージの名前になってます。どんなのが入ってるのかなと言うと、上からザーっと説明しちゃうんですけれども。

特殊な値を持っているDataValuesと、テーブル全体のインターフェースになっているIterableTablesと、Queryっていうのはさっきのパイプみたいなやつと、VegaLiteっていうのは可視化のときに使うやつとか、FileIOっていうのはファイルをIOするものなんですけど。

そういうのがダーっと入ってて、よく見てみると、Queryverse叩くとさっき紹介したDataFramesも読み込んでるっていう。けっこう貪欲な仕様になっています。

Queryverse読み込むとそのままDataFramesも入るので、Queryverseをインストールするのがいいんじゃないかとは思うんですけれども、Queryverseは非常にインストールが厄介でして。あまりにも多くパッケージを含んでいるせいか、だいたいどっかが依存関係でコケます。

(会場笑)

1回でインストールできることはたぶんないです。試しにみなさんの環境で「 add Queryverse」って入れてみるとたぶんどっかでコケると思います。UbuntuでやってもMacでやってもコケたんで。

だいたいそのあとでライブラリかなんかを別で自分で引っ張ってきて、何度か直してビルドをもう1回叩くみたいなことをしなきゃいけない(笑)。そういうパッケージになってます。

Queryverseも、正直言ってできることは一緒です。filepathからloadしてきたirisっていうのでCSVを読むことができて、パイプ処理もできると。さっきより読みやすいかなと僕は思ってます。

irisからSepalLengthで条件を付けてfilterして、グルーピングを行って、今度はそれぞれからmeanとか使ってグルーピングしたものでどういう仕分けをするかを指定してあげて、最後それぞれまた足したりっていうことをやってあげる。

選択肢がある、しかし…

今ざっくり3つ紹介しましたが、なるほどと。

確かに3つもある。tidyverseとかPandasみたいなパッケージは、実質あっち(RとPythonに)は1個しかない。こっちは選択肢がいっぱいある。すばらしいことじゃないかと。

オッケー、オッケー。

じゃあSepalLengthが6より大きいものの行を持ってきたいなぁと思ったら、残念、今回は候補が4つあります。

DataFramesではこう書く。DataFramesMetaではこう書く。JuliaDBではこう書く。Queryverseではこう書く。

じゃあこれを全部覚えといて毎回良いところ悪いところで使いこなしてくださいと言われると、なんだそれはということになってしまいますので(笑)。もちろんどれがいいかなという話をしたいなと思います。

今までちょっと触れてこなかったんですが、実はバージョンによってまだ動かないところが1個だけあるんです。まずバージョン1.0.1ではJuliaDBは動きません。(※講演時点)

インストール叩いても「お前のバージョンでは今は対応してないよ」って怒られるだけです。なので先ほど見せたコードも実はJuliaDBだけは0.6.4で回してました。

DataFramesとDataFramesMeta、Queryverseは1.0.1でもインストールできますし動きます。ただしQueryverseはたぶんコケます。がんばってください。一応がんばれば使えます。

なので現実的には気軽に始めたい方、R、tidyverse、Python、Pandasからちょっと違うことしてみたいなという方には、DataFramesとDataFramesMetaをおすすめしたいと思います。今から始めても、1からでも大丈夫。

もっとトリッキーなことがしたいという方には、Queryverseをおすすめしたいと思います。Queryverseインストールバトルをぜひがんばってください。