🏹
Red Arrowでカラム名の変更
できません。
けど、Red Arrowを使ったデータフレームライブラリーであるRedAmberではできるんですよね:
df.rename(:old_name => :new_name)
どうやっているんだろうと見てみました[1]。
色々やった後にrename_by_hash
に投げています。
rename_by_hash
の実装は:
Arrow::Table
を作り直していました。
と言ってもデータその物をコピーしたりはせずに、データの名前や型定義であるスキーマだけ作り直してArrow::Table
を作っています(new
の第一引数):
Arrow::Table.new(Arrow::Schema.new(fields), @table.columns)
これはまあ、できるのはできるけどめんどくさいので、やっぱデータフレームライブラリーあると便利ですね。
仮実装
RedAmberを入れるほどじゃないんだけどカラム名の変更だけしたい、みたいな場合はこんなパッチでいけます:
module ArrowRefinement
refine Arrow::Table do
def rename_column(from, to=nil)
case
when from.kind_of?(String) && to.nil?
raise ArgumentError, "to is missing"
when from.kind_of?(Hash) && to
raise ArgumentError, "to is not needed"
end
renames = (from.kind_of?(String) ? {from => to} : from)
.transform_keys(&:to_s)
fields = column_names.collect {|name|
if to = renames[name]
from = self[name]
raise ArgumentError, "column #{name} not found in from" unless from
Arrow::Field.new(to, from.data_type)
else
schema[name]
end
}
Arrow::Table.new(Arrow::Schema.new(fields), columns)
end
end
end
using ArrowRefinement
Arrow::Table.load("path/to/data")
.rename_column("変更前", "変更後")
.rename_column(
"変更前1" => "変更後1",
"変更前2" => "変更前2",
"変更前3" => "変更前3"
)
self
じゃなくて新しいArrow::Table
を返すのが気持ち悪い人はいるかも知れない。そういうAPIはRed Arrowでも見掛けるからいいとは思うけど。
-
RedAmber v0.5.2 ↩︎
Discussion