Polarsで日本語処理や祝日判定など、日本の人が少し便利になる機能を詰め合わせたライブラリ、polars-japaneseを作成しました。
たとえばこんなことができます。
- 和暦 ↔ datetime 変換
- 祝日判定・曜日取得
- 全角 ↔ 半角 変換
- 漢数字変換
- 都道府県 → 地方 変換
- Shift-JISでCSV出力
本記事では主な機能と背景技術について紹介します。
※この記事はPolars Data Crunch #4で発表した内容がベースですが、新たに追加した機能の説明も含んでいます1
概要
3行でわかる使い方
インストール
pip install polars-japanese
使用
import polars_japanese
# 和暦(例: "令和2年2月2日")で入っているデータをdatetimeに変換
df.select(pl.col("出生日").ja.to_datetime())
手順としては、インストール、インポートしたら ja
アクセサが使えるようになります。.str
や .dt
と同じように、普通にExpressionに続けて使うことができます。
注意事項
- installとimportで名前が微妙に違うので(ハイフン
-
とアンスコ_
)、その点ご注意ください。japanize-matplotlib に倣ってます -
import polars_japanese
は必要なものの、コード内で直接使用はしないので、Ruffなどに怒られる場合は# noqa: F401
を書いておくことを推奨します
関連リンク
- Github: https://github.com/tanaka-jin/polars-japanese
- Docs: https://polars-japanese.readthedocs.io/ja/
- PyPI: https://pypi.org/project/polars-japanese/
主な機能
1. 全角・半角変換
-
.ja.to_half_width()
,.ja.to_full_width()
.ja.normalize()
全角・半角変換は、数字、カタカナ、ascii(アルファベットなど)を変換します。Rustのmojimoji-rsをwrapしたものです。
normalize
は、 polars.str.normalize
によるNFKC正規化に加えて、jaconvに倣い、伸ばし棒(―‐˗֊‐‑‒–⁃⁻₋−
)の統一などの処理を行っています。
2. 和暦変換
.ja.to_datetime(format='%-K%-y年%m月%d日', raise_error=True)
.ja.to_wareki(format='%-K%-Y年%m月%d日', raise_error=True)
文字列で持ってる和暦とDatetime型の変換です。
japaneraを呼び出しているので、format
を %-K
と指定すると漢字(昭和、令和)、%-E
にするとローマ字の和暦(Showa, Reiwa)へと変換するなど、フォーマットの指定が可能です。
平成50年など、存在しない和暦が指定されている場合にエラーを吐くか欠損にするかを raise_error
で指定しています。
3. 漢数字変換
.ja.to_kanji(config=None)
.ja.to_number()
kanjizeをwrapしたものです。漢字表記の仕方はkanjizeのconfigをそのまま引数として渡しているので、たとえば二〇〇〇/二千/2千、〇/零など、細かく制御できるようになっています。
4. 祝日判定・曜日取得
.ja.is_holiday()
.ja.is_business_day()
.ja.to_weekday_name(format="%A")
祝日判定はJPHolidayをwrapしたものです。is_business_day
は土日と祝日の場合Falseを返します2。
曜日取得は、デフォルトでは「月曜日」「火曜日」が返されますが、format="%a"
とすると「月」「火」を取得できます。
5. 都道府県変換
.ja_pref.to_code()
.ja_pref.to_kanji()
.ja_pref.to_hiragana()
.ja_pref.to_katakana()
.ja_pref.to_romaji()
.ja_pref.to_region()
都道府県名(漢字、かな、ローマ字)と都道府県コード間の変換ができます。名前は「青森県」のような書き方にも「青森」のような書き方にも対応しています。
また、to_region
で地方への変換を行えます。地方の定義は複数ありますが、おそらく最も一般的であろう八地方区分を採用しています3。
注意事項: この機能は .ja
アクセサではなく .ja_pref
アクセサから使用できます。
6. CSV出力
.ja.write_csv(path, encoding="shift-jis")
polarsの write_csv
だと、文字コードの指定ができません4。
たまにShift-JISなどで出力したくなるときが発生するので、nkayさんのこちらの記事をもとに実装しました。ありがとうございます!
背景技術
namespace
-
register_expr_namespace
,register_dataframe_namespace
PolarsのExpressionに続けて書ける処理を、 .str
や .dt
と同じように使える形で追加できる。これを用いてExpr -> Exprのメソッドを登録することで、ja
アクセサで使えるようになる。
plugin
register_plugin_function
Rustで実装したものをpythonから呼び出せるようにするための機能がプラグイン。Polarsから呼び出せるようにRust側、Python側双方で設定が必要5。
おまけ
小さなこだわりとして、このライブラリのなかでゼロから全て作るのではなく、既存のライブラリを流用する形を優先しています。作成手間を避けつつ、細かい制御が可能になっているかと思います。
その分 map_elements
を多用する形になってしまっているので、スピードとの兼ね合いを考えて今後変更する可能性はあります。
参考になったもの
- Polars plugins tutorial
- Plugins - Polars user guide
- Polars Expression Plugins
- polarsのudfとかpluginとか触ってみた - Speaker Deck
今後の展望
ニーズがあるかなどをあまり考えずに作ってしまったのですが、継続で開発していく気持ちはありますので、「こんな機能も欲しい」「ここが使いずらい」などあったらフィードバックいただけると飛んで喜びます。
また、一緒に開発することに興味ある方がいらっしゃったらpolars-jaのdiscordより連絡ください!
-
Polars Data Crunch #4 の イベントページ: https://polars-ja.connpass.com/event/352216/ , LT資料: https://speakerdeck.com/jinta/polars-japanese-lt , 動画: https://youtube.com/live/h0tg7GQ2RNE?feature=share ↩
-
現実点では、Polars 1.27で追加された
is_business_day
は使用していません。そのうち変更するかもです。参考: https://speakerdeck.com/ghibney/polars-1-dot-1-0yi-jiang-noshi-eruxin-ji-neng?slide=15 ↩ -
北海道、東北、関東、中部、近畿、中国、四国、九州・沖縄の8つの地方。https://makitani.net/shimauma/knowledge/regional-classification-of-japan ここはすぐに拡張するかもです。 ↩
-
https://docs.pola.rs/api/python/stable/reference/api/polars.DataFrame.write_csv.html ↩
-
LLMに書いてもらっていて正直どう働いているかはあまり理解してないので、詳細はごめんなさい。 ↩