12
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RedAmberを触ってみた

Last updated at Posted at 2023-05-13

データフレーム(2次元の表形式のデータ)を用意されていて、それに何かしらの処理しようと思った時パッと思い浮かぶ利用ツールはPythonのPandasでしょうか?それともExcelなどでしょうか?
今回はそのどちらでもなく、RubyKaigiでも紹介されたRubyのgemの一つであるRedAmberを触ってみます。

RedAmberとは?

データフレームを扱うためのRubyのライブラリです。(ソースコードは下記)
ApacheArrowのRubybindingであるRedArrowが中では動いているみたいです。

詳細は開発者の方がRubyKaigiで発表したスライドがあります。

検証環境

今回は下記の環境で使ってみます。

  • Ruby 3.2.2
  • M1 Pro

セットアップ

Readmeを参考に下記コマンドを実行します。

brew install apache-arrow
brew install apache-arrow-glib

RedAmberを動かすためにはRedArrowが必要で、RedArrowを動かすためにはApacheArrowが必要、というわけでApacheArrowをインストールしているわけですね。

次に、RedAmberをインストールします。
今回はGemfileを使ってbundle installします。(普通にgem install red_amberでもいいと思います)
データセットのサンプルとして、red-datasets-arrowも一緒にインストールしています。

Gemfile
# -*- mode: ruby -*-
# frozen_string_literal: true

source 'https://rubygems.org'

ruby '3.2.2'

gem 'red_amber'
gem 'red-datasets-arrow'

https://github.com/red-data-tools/red-datasets からデータセットの情報を見ることができます。
今回はIrisを使ってみましょう。

まずはデータを覗いてみます。まずは読み込んで出力してみましょう。

p_iris.rb
require 'datasets-arrow'
require 'red_amber'
include RedAmber
dataset = Datasets::Iris.new
iris = DataFrame.new(dataset) # before v0.2.3, should be `dataset.to_arrow`
p iris
#<RedAmber::DataFrame : 150 x 5 Vectors, 0x000000000000337c>
    sepal_length sepal_width petal_length petal_width label
        <double>    <double>     <double>    <double> <string>
  0          5.1         3.5          1.4         0.2 Iris-setosa
  1          4.9         3.0          1.4         0.2 Iris-setosa
  2          4.7         3.2          1.3         0.2 Iris-setosa
  3          4.6         3.1          1.5         0.2 Iris-setosa
  4          5.0         3.6          1.4         0.2 Iris-setosa
・・・(中略)
146          6.3         2.5          5.0         1.9 Iris-virginica
147          6.5         3.0          5.2         2.0 Iris-virginica
148          6.2         3.4          5.4         2.3 Iris-virginica
149          5.9         3.0          5.1         1.8 Iris-virginica

ヘタと花弁の縦横(?)の長さ、それとIrisの種類の5項目が表示されました。

次にlabelごとに平均を出してみましょう。

まずは、label毎にデータセットを分割する必要がありますが、それはgroupを使うことで解決します。
先ほどのプログラムを少し変えて、irisをgroup関数を使って分けてみましょう。

ave_group_label.rb
require 'datasets-arrow'
require 'red_amber'
include RedAmber
dataset = Datasets::Iris.new
iris = DataFrame.new(dataset)

df = iris
  .group(:label)

p df

実行するとこんな感じ。

ruby ave_group_label.rb
#<RedAmber::Group : 0x000000000000337c>
  label             count
  <string>        <int64>
0 Iris-setosa          50
1 Iris-versicolor      50
2 Iris-virginica       50

ラベルとラベルを振られた数が表示されています。3つのラベルが50ずつあるのがわかります。

さらにmeanを使ってlabel毎のそれぞれの平均を出してみましょう。

df = iris
  .group(:label)
+ .mean(:sepal_length, :sepal_width, :petal_length, :petal_width)

実行すると、それぞれの値の平均を出してくれます。

❯ ruby ave_group_label.rb
#<RedAmber::DataFrame : 3 x 5 Vectors, 0x000000000000337c>
  label           mean(sepal_length) mean(sepal_width) mean(petal_length) mean(petal_width)
  <string>                  <double>          <double>           <double>          <double>
0 Iris-setosa                   5.01              3.42               1.46              0.24
1 Iris-versicolor               5.94              2.77               4.26              1.33
2 Iris-virginica                6.59              2.97               5.55              2.03

さらに今回はsepal_widthを基準にソートしてみましょう。下記を追記するとソートしてくれます。

df = iris
  .group(:label)
  .mean(:sepal_length, :sepal_width, :petal_length, :petal_width)
+ .sort('-mean(sepal_length)')

実行してみると、sepal_widthが高いlabel順にソートされています。

❯ ruby ave_group_label.rb
#<RedAmber::DataFrame : 3 x 5 Vectors, 0x000000000000337c>
  label           mean(sepal_length) mean(sepal_width) mean(petal_length) mean(petal_width)
  <string>                  <double>          <double>           <double>          <double>
0 Iris-setosa                   5.01              3.42               1.46              0.24
1 Iris-virginica                6.59              2.97               5.55              2.03
2 Iris-versicolor               5.94              2.77               4.26              1.33

低い方から出したい時は、sortの部分を一部変えると良いです。

df = iris
  .group(:label)
  .mean(:sepal_length, :sepal_width, :petal_length, :petal_width)
- .sort('-mean(sepal_length)')
+ .sort('+mean(sepal_length)')
❯ ruby ave_group_label.rb
#<RedAmber::DataFrame : 3 x 5 Vectors, 0x000000000000337c>
  label           mean(sepal_length) mean(sepal_width) mean(petal_length) mean(petal_width)
  <string>                  <double>          <double>           <double>          <double>
0 Iris-versicolor               5.94              2.77               4.26              1.33
1 Iris-virginica                6.59              2.97               5.55              2.03
2 Iris-setosa                   5.01              3.42               1.46              0.24

触ってみて

ActiveRecordを触ったことがあってSQLもそこそこ描ける人なら、ActiveRecord触っている感覚でデータをサクサクと集計などを進めることができそうです。
今後ちょっとした集計などではRedAmberを使ってみて、フィードバックとしてPRやIssueも出していきたいです。
今回触れた機能はごく一部でまだまだいろんなことができるので、気になった人は是非リポジトリを覗いてみてください。

おまけ

今回作ったコードはここにアップしてあります。
https://github.com/Umekawa/red_amber_demo

12
5
1

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
12
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?