Apache Arrowでフィルタリング

2025/02/26に公開

問題

ID カテゴリー
1 A
2 B
3 C
4 A
5 B
6 C

みたいな表から、カテゴリーがBとCの物だけ取り出したい[1]

方針: Arrow::Table#slice

慣れているのでここではRubyを使うけど、多分どの言語も同じ考え方でいけると思う。

#sliceの使い方は、簡単なのはドキュメントを見れば分かるんだけど、ぱっと見、合いそうな物がない。怪しいのはブロックを使う物ぐらい。ただブロックバージョンはドキュメントを見ても使い方が分からないのでテストを見るのがよい[2]

こういうテストがあって、今回はこれが使えそう:


  test("column.in") do
    sliced_table = @table.slice do |slicer|
      slicer.count.in?([1, 4, 16, 64])
    end
    assert_equal(<<-TABLE, sliced_table.to_s)
	   count	visible
	(uint32)	 (bool)
0	       1	true   
1	       4	 (null)
2	      16	true   
3	      64	 (null)
    TABLE
  end

解答

今回はこうなる筈:

  table = Arrow::Table.new(
    ID: [1, 2, 3, 4, 5, 6],
    カテゴリー: ["A", "B", "C", "A", "B", "C"]
  )
  interest_categories = ["B", "C"]
  slice = table.slice {|slicer| slicer.カテゴリー.in? interest_categories}
  pp slice
#<Arrow::Table:0x00000001257181c8 ptr=0x00006000002085b0>
             ID  カテゴリー
        (uint8) (utf8)
0             2 B
1             3 C
2             5 B
3             6 C

脚注
  1. RubyでArrowを使ったデータフレームライブラリーとしてRedAmberがあるけど、Red ArrowだけでもかなりのことができるのでここではRed Arrowでやってみたい。 ↩︎

  2. 行毎にRubyのブロックを呼び出していたら遅くて仕方がないから、内部では多分Arrowでの操作に変換しているんだろうけど、結構(Rubyとして)自然な書き方でフィルタリングできるので驚く。 ↩︎

Discussion