mcpField
X
xsv

xsv

公式Agent-ready
github.comデータベース・データ10.8kxsv79 週間前に更新
リポジトリ公式サイト

xsv について

xsv は高性能の CSV 処理ツールで、インデックス、スライシング、結合、統計分析機能を提供します。Rust で記述されており、大規模 CSV ファイルの効率的な処理を実現します。

主な機能

  1. 01CSV ファイル内の列と行をインデックス・検索する
  2. 02カウント、合計、平均などの統計情報を計算する
  3. 03複数の CSV ファイルを結合・連結・変換する

活用シーン

  1. 01データワークフローで CSV ファイルを効率的に処理するコーディングエージェント
  2. 02ログ、設定、データエクスポートファイルを分析・変換する開発者

インストール

OS またはパッケージマネージャーを選び、コマンドをターミナルで実行します。

$
brew install xsv

インストール後にxsv --versionを実行して確認します。

コマンド例

よく使うコマンドを使う順に並べています。

01
xsv headers data.csv
02
xsv stats data.csv

詳細

xsv は現在メンテナンスされていません

xsv の代わりに、 qsv または xan をおすすめします。


xsv は、CSV ファイルのインデックス作成、行の抽出、分析、分割、結合を行うコマンドラインプログラムです。各コマンドはシンプルで、高速かつ組み合わせやすいことを目指しています。

  1. 簡単なタスクは、簡単に実行できるべきです。
  2. パフォーマンス上のトレードオフは、CLI インターフェイスで明示されるべきです。
  3. パフォーマンスを犠牲にして、コマンドの組み合わせやすさを実現してはなりません。

この README では、いくつかのコマンドの簡単な紹介に加えて、 xsv のインストール方法を説明しています。

Linux ビルドステータス Windows ビルドステータス README の画像

MIT または UNLICENSE のデュアルライセンスです。

利用可能なコマンド
  • cat - CSV ファイルを行または列単位で連結します。
  • count - CSV ファイルの行数を数えます(インデックスがあれば瞬時に完了します)。
  • fixlengths - レコードのパディングまたは切り詰めによって、CSV ファイルの各レコードの長さをそろえます。
  • flatten - CSV レコードをフラット化して表示します。レコードを1つずつ確認するのに便利です。例:xsv slice -i 5 data.csv | xsv flatten。
  • fmt - 区切り文字、レコード終端文字、引用符のルールを変更して CSV データを再フォーマットします(ASCII 区切りデータに対応しています)。
  • frequency - CSV データの各列の度数表を作成します(インデックスがある場合、並列処理によって高速化します)。
  • headers - CSV データのヘッダーを表示します。または、複数の CSV ファイルに共通するすべてのヘッダーを表示します。
  • index - CSV ファイルのインデックスを作成します。非常に高速で、CSV ファイルを定数時間でインデックス参照できます。
  • input - 特殊な引用符やエスケープのルールを使って CSV データを読み込みます。
  • join - 内部結合、外部結合、クロス結合を行います。シンプルなハッシュインデックスを使って高速に処理します。
  • partition - 列の値に基づいて CSV データを分割します。
  • sample - リザーバーサンプリングを使って、CSV データから行をランダムに抽出します(つまり、サンプルのサイズに比例するメモリを使用します)。
  • reverse - CSV データの行の順序を逆にします。
  • search - CSV データに正規表現を適用します。各フィールドに個別に正規表現を適用し、一致した行のみを表示します。
  • select - CSV データから列を選択、または並べ替えます。
  • slice - CSV ファイルの任意の部分から行を抽出します。インデックスがある場合は、スライスの開始位置より前のすべての行ではなく、スライス内の行のみを解析します。
  • sort - CSV データを並べ替えます。
  • split - 1つの CSV ファイルを N 個のチャンクからなる複数の CSV ファイルに分割します。
  • stats - CSV ファイルの各列の基本的な型と統計情報を表示します(平均、標準偏差、中央値、範囲など)。
  • table - elastic tabstops を使って、あらゆる CSV データを整列して表示します。
ざっと見てみましょう

Data Science Toolkitのデータを使ってみることにしましょう。このデータには複数の CSV ファイルが含まれています。たとえば、世界各都市の人口に関心があるとします。データを取得して、調べ始めてみましょう。

$ curl -LO https://burntsushi.net/stuff/worldcitiespop.csv
$ xsv headers worldcitiespop.csv
1   Country
2   City
3   AccentCity
4   Region
5   Population
6   Latitude
7   Longitude

次に、各列にどのようなデータが含まれているか、概要を確認したくなるかもしれません。stats コマンドを使えば確認できます。

$ xsv stats worldcitiespop.csv --everything | xsv table
field       type     min            max            min_length  max_length  mean          stddev         median     mode         cardinality
Country     Unicode  ad             zw             2           2                                                   cn           234
City        Unicode   bab el ahmar  Þykkvibaer     1           91                                                  san jose     2351892
AccentCity  Unicode   Bâb el Ahmar  ïn Bou Chella  1           91                                                  San Antonio  2375760
Region      Unicode  00             Z9             0           2                                        13         04           397
Population  Integer  7              31480498       0           8           47719.570634  302885.559204  10779                   28754
Latitude    Float    -54.933333     82.483333      1           12          27.188166     21.952614      32.497222  51.15        1038349
Longitude   Float    -179.983333    180            1           14          37.08886      63.22301       35.28      23.8         1167162

xsv table コマンドは、CSV データを受け取り、elastic tabstopsを使って列を揃えて表示します。Unicode 文字でも正しく揃うことがわかります。

このコマンドは私のマシンでは実行に約 12 秒かかりますが、インデックスを作成してからコマンドを再実行すれば高速化できます。

$ xsv index worldcitiespop.csv
$ xsv stats worldcitiespop.csv --everything | xsv table
...

これで私のマシンでは約 8 秒に短縮されます(インデックスの作成にかかる時間は 2 秒未満です)。

注目すべきことに、別のCSV コマンドラインツールキットにある同様の「統計」コマンドでは、同じデータセットから同様の統計を出力するのに約 2 分かかります。

インデックスを作成すると、統計の取得が速くなるだけではありません。スライス操作も非常に速くなります。解析が必要なのは、スライスした部分だけだからです。たとえば、最後の 10 レコードを取得したいとします。

$ xsv count worldcitiespop.csv
3173958
$ xsv slice worldcitiespop.csv -s 3173948 | xsv table
Country  City               AccentCity         Region  Population  Latitude     Longitude
zw       zibalonkwe         Zibalonkwe         06                  -19.8333333  27.4666667
zw       zibunkululu        Zibunkululu        06                  -19.6666667  27.6166667
zw       ziga               Ziga               06                  -19.2166667  27.4833333
zw       zikamanas village  Zikamanas Village  00                  -18.2166667  27.95
zw       zimbabwe           Zimbabwe           07                  -20.2666667  30.9166667
zw       zimre park         Zimre Park         04                  -17.8661111  31.2136111
zw       ziyakamanas        Ziyakamanas        00                  -18.2166667  27.95
zw       zizalisari         Zizalisari         04                  -17.7588889  31.0105556
zw       zuzumba            Zuzumba            06                  -20.0333333  27.9333333
zw       zvishavane         Zvishavane         07      79876       -20.3333333  30.0333333

これらのコマンドは、スライスのサイズに比例する時間とメモリで実行されるため、瞬時に完了します(つまり、どれほど大きな CSV データにも対応できます)。

少し話を変えましょう。CSV データのすべての列を常に見たいとは限りません。この場合、必要なのは国、都市、人口だけかもしれません。それでは、ランダムに選んだ 10 行を見てみましょう。

$ xsv select Country,AccentCity,Population worldcitiespop.csv \
  | xsv sample 10 \
  | xsv table
Country  AccentCity       Population
cn       Guankoushang
za       Klipdrift
ma       Ouled Hammou
fr       Les Gravues
la       Ban Phadèng
de       Lüdenscheid      80045
qa       Umm ash Shubrum
bd       Panditgoan
us       Appleton
ua       Lukashenkivske

おっと!人口が記録されていない都市があるようです。どの程度よくあることでしょうか?

$ xsv frequency worldcitiespop.csv --limit 5
field,value,count
Country,cn,238985
Country,ru,215938
Country,id,176546
Country,us,141989
Country,ir,123872
City,san jose,328
City,san antonio,320
City,santa rosa,296
City,santa cruz,282
City,san juan,255
AccentCity,San Antonio,317
AccentCity,Santa Rosa,296
AccentCity,Santa Cruz,281
AccentCity,San Juan,254
AccentCity,San Miguel,254
Region,04,159916
Region,02,142158
Region,07,126867
Region,03,122161
Region,05,118441
Population,(NULL),3125978
Population,2310,12
Population,3097,11
Population,983,11
Population,2684,11
Latitude,51.15,777
Latitude,51.083333,772
Latitude,50.933333,769
Latitude,51.116667,769
Latitude,51.133333,767
Longitude,23.8,484
Longitude,23.2,477
Longitude,23.05,476
Longitude,25.3,474
Longitude,23.1,459

(xsv frequency コマンドは、CSV データの各列の度数表を作成します。今回は 5 秒しかかかりませんでした。)

どうやら、ほとんどの都市には人口がまったく登録されていないようです。問題ありません。人口が登録されている行だけを表示するよう、先ほどのコマンドを調整できます。

$ xsv search -s Population '[0-9]' worldcitiespop.csv \
  | xsv select Country,AccentCity,Population \
  | xsv sample 10 \
  | xsv table
Country  AccentCity       Population
es       Barañáin         22264
es       Puerto Real      36946
at       Moosburg         4602
hu       Hejobaba         1949
ru       Polyarnyye Zori  15092
gr       Kandíla          1245
is       Ólafsvík         992
hu       Decs             4210
bg       Sliven           94252
gb       Leatherhead      43544

うーん。at はどの国でしょうか?まったくわかりませんが、Data Science Toolkit には countrynames.csv という CSV ファイルがあります。これを取得して結合すれば、どの国なのか確認できます。

curl -LO https://gist.githubusercontent.com/anonymous/063cb470e56e64e98cf1/raw/98e2589b801f6ca3ff900b01a87fbb7452eb35c7/countrynames.csv
$ xsv headers countrynames.csv
1   Abbrev
2   Country
$ xsv join --no-case  Country sample.csv Abbrev countrynames.csv | xsv table
Country  AccentCity       Population  Abbrev  Country
es       Barañáin         22264       ES      Spain
es       Puerto Real      36946       ES      Spain
at       Moosburg         4602        AT      Austria
hu       Hejobaba         1949        HU      Hungary
ru       Polyarnyye Zori  15092       RU      Russian Federation | Russia
gr       Kandíla          1245        GR      Greece
is       Ólafsvík         992         IS      Iceland
hu       Decs             4210        HU      Hungary
bg       Sliven           94252       BG      Bulgaria
gb       Leatherhead      43544       GB      Great Britain | UK | England | Scotland | Wales | Northern Ireland | United Kingdom

おっと、Country という列が 2 つと、もう不要な Abbrev 列ができてしまいました。xsv select コマンドで列の順序を変えれば、簡単に修正できます。

$ xsv join --no-case  Country sample.csv Abbrev countrynames.csv \
  | xsv select 'Country[1],AccentCity,Population' \
  | xsv table
Country                                                                              AccentCity       Population
Spain                                                                                Barañáin         22264
Spain                                                                                Puerto Real      36946
Austria                                                                              Moosburg         4602
Hungary                                                                              Hejobaba         1949
Russian Federation | Russia                                                          Polyarnyye Zori  15092
Greece                                                                               Kandíla          1245
Iceland                                                                              Ólafsvík         992
Hungary                                                                              Decs             4210
Bulgaria                                                                             Sliven           94252
Great Britain | UK | England | Scotland | Wales | Northern Ireland | United Kingdom  Leatherhead      43544

元の CSV データに対してこれを実行することもできるでしょうか?もちろんできます。xsv の結合は高速だからです。

$ xsv join --no-case Abbrev countrynames.csv Country worldcitiespop.csv \
  | xsv select '!Abbrev,Country[1]' \
  > worldcitiespop_countrynames.csv
$ xsv sample 10 worldcitiespop_countrynames.csv | xsv table
Country                      City                   AccentCity             Region  Population  Latitude    Longitude
Sri Lanka                    miriswatte             Miriswatte             36                  7.2333333   79.9
Romania                      livezile               Livezile               26      1985        44.512222   22.863333
Indonesia                    tawainalu              Tawainalu              22                  -4.0225     121.9273
Russian Federation | Russia  otar                   Otar                   45                  56.975278   48.305278
France                       le breuil-bois robert  le Breuil-Bois Robert  A8                  48.945567   1.717026
France                       lissac                 Lissac                 B1                  45.103094   1.464927
Albania                      lumalasi               Lumalasi               46                  40.6586111  20.7363889
China                        motzushih              Motzushih              11                  27.65       111.966667
Russian Federation | Russia  svakino                Svakino                69                  55.60211    34.559785
Romania                      tirgu pancesti         Tirgu Pancesti         38                  46.216667   27.1

!Abbrev,Country[1] という構文は、「Abbrev 列を削除し、Country 列の 2 つ目の出現箇所を削除する」という意味です。最初に countrynames.csv と結合したので、最初の Country 名(完全な名前)が CSV データに含まれています。

この xsv join コマンドは、私のマシンでは約 7 秒かかります。高速なのは、指定した CSV データファイルの 1 つに非常にシンプルなハッシュインデックスを作成するためです。join コマンドはデフォルトで内部結合を行いますが、左外部結合、右外部結合、完全外部結合にも対応しています。

インストール

Windows、Linux、macOS 用のバイナリはGithubから入手できます。

macOS Homebrew ユーザーの場合は、homebrew-core から xsv をインストールできます。

$ brew install xsv

macOS MacPorts ユーザーの場合は、公式ポートから xsv をインストールできます。

$ sudo port install xsv

Nix/NixOS ユーザーの場合は、nixpkgs から xsv をインストールできます。

$ nix-env -i xsv

または、Cargo(Rust のパッケージマネージャー)をインストールし、Cargo を使って xsv をインストールすれば、ソースからコンパイルできます。

cargo install xsv

このリポジトリからコンパイルする場合も、同様の手順で行えます。

git clone git://github.com/BurntSushi/xsv
cd xsv
cargo build --release

コンパイルには、お使いのマシンによって数分かかることがあります。バイナリは ./target/release/xsv に生成されます。

ベンチマーク

さまざまな xsv コマンドのおおまかなベンチマークをいくつか作成しました。

開発の動機

このプロジェクトには、次のような妥当な批判がいくつかあります。

  1. CSV はひどい形式なので、CSV データを扱うべきではありません。
  2. データがギガバイト単位なら、CSV は適切なストレージ形式ではありません。
  3. さまざまな SQL データベースでは、より高度なインデックス機能を備えながら、xsv で利用できるすべての操作を実行できます。しかも、パフォーマンスは何億倍も優れています。

ほかにも批判はあると思いますが、このプロジェクトのきっかけは、私に渡された 40GB の CSV ファイルでした。その中のデータの構造を把握し、既存のシステムに統合する方法を考えるよう依頼されたのです。そのとき、私が知っている CSV ツールはどれもまったく不十分だと気づきました。処理が遅すぎるか、柔軟性が足りなかったのです。(別のプロジェクトでは、数十個の CSV ファイルを扱っていました。それぞれは 40GB より小さいものの、同じ種類のデータを表すはずでした。しかし、列の構成が異なり、列名も直感的ではありませんでした。ここでは便利な CSV 検査ツールが不可欠であり、しかも十分な速さが必要でした。)

作業に役立った重要な機能は、インデックス作成、ランダムサンプリング、検索、スライス、列の選択でした。こうした機能がすべて、40GB の CSV データ(または数十個の CSV ファイル)を少し扱いやすくしてくれました。

一度でも巨大な CSV ファイルを渡されれば、私がこの探求に乗り出すには十分でした。他の人たちとの会話からすると、これほど大きな CSV データファイルは珍しくないようです。ですから、これほど大きなデータを扱える可能性のあるツールには、存在意義があると考えています。

名前の重複

このプロジェクトは、同じ名前を持つ、よく似た別のプロジェクトとは無関係です。 https://mj.ucw.cz/sw/xsv/

コメント