在终端舒适地进行数据可视化
摘要
xan 是一个用 Rust 编写的高性能命令行 CSV 处理工具,具备 SIMD 解析、并行计算和终端数据可视化功能。
查看缓存全文
缓存时间: 2026/06/17 17:53
medialab/xan 源代码:https://github.com/medialab/xan 构建状态(https://github.com/medialab/xan/actions) DOI(https://doi.org/10.5281/zenodo.15310200) # xan,CSV 魔术师
xan 是一个命令行工具,可直接在 shell 中处理 CSV 文件。它用 Rust 编写,力求速度最快、内存占用最小,并能轻松处理大型 CSV 文件(数 GB 级别)。它采用了一种新颖的 SIMD(单指令多数据流)CSV 解析器(https://docs.rs/simd-csv),并且可以并行化某些计算(通过多线程),从而尽可能快地完成某些任务。它可以轻松预览、过滤、切片、聚合、排序、连接 CSV 文件,并提供大量可组合的命令,这些命令可以链接在一起以执行各种典型任务。xan 还提供了自己的表达式语言,因此你可以执行无法通过简单命令完成的复杂任务。这种极简的语言专为 CSV 数据定制,比评估典型的动态类型语言(如 Python、Lua、JavaScript 等)快得多。
请注意,该工具最初是 BurntSushi(https://github.com/BurntSushi)的 xsv(https://github.com/BurntSushi/xsv)的一个分支,但到目前为止几乎完全重写,以适应 SciencesPo 的 médialab(https://github.com/medialab)的用例,其根源在于面向社会科学的网络数据收集和分析(你可能认为 CSV 现在已经过时,但在过于匆忙地评判之前,请阅读我们写给该格式的情书)。因此,xan 超越了典型的数据操作,并提供了与词汇计量、图论甚至爬取相关的实用程序。除了 CSV 数据,xan 还能处理来自许多不同学科的、与 CSV 相邻的多种数据格式,例如网络存档(.cdx)或生物信息学(.vcf、.gtf、.sam、.bed 等)。xan 还能够使用 xan to 和 xan from 与许多数据格式(如 json、Excel 文件、numpy 数组等)相互转换。有关详细信息,请参阅此部分。
最后,xan 可用于在终端中显示 CSV 文件,便于探索,甚至可以用于绘制基本的数据可视化:
| view 命令 | flatten 命令 |
|---|---|
| view | flatten |
| 分类直方图 | 散点图 |
| categ-hist | correlation |
| 分类散点图 | 直方图 |
| scatter | hist |
| 并行处理 | 时间序列 |
| parallel | series |
| 小倍数(面板网格) | 分组视图 |
| small-multiples | view-grid |
| 相关性矩阵热图 | 热图 |
| small-multiples | view-grid |
目录
- 如何安装
- Cargo
- Scoop (Windows)
- Homebrew (macOS)
- Arch Linux
- NetBSD
- Nix
- Pixi
- Conda Forge
- 预构建的二进制文件
- 安装补全
- 快速入门
- 学习
- 可用命令
- 通用标志和 IO 模型
- 获取帮助
- 关于输入和输出格式
- 处理无头 CSV 文件
- 关于标准输入
- 关于标准输出
- 支持的文件格式
- 压缩文件
- 关于颜色
- 表达式语言参考
- 新闻
- 如何引用?
- 常见问题解答
如何安装
Cargo
可以使用 cargo 安装 xan(它通常随 Rust(https://www.rust-lang.org/tools/install)一起提供):
cargo install xan --locked
可选功能 某些功能由于编译时间或可执行文件大小成本过高,默认不构建。以下是可选功能的列表:
parquet:启用xan from -f parquet
你可以按如下方式指定要启用的可选功能:
# 启用所有可选功能
cargo install xan --locked --all-features
# 仅启用特定功能
cargo install xan --locked --features parquet
你还可以调整构建标志,以确保 Rust 编译器能够利用 CPU 的所有功能:
CARGO_BUILD_RUSTFLAGS='-C target-cpu=native' cargo install xan --locked
你也可以按如下方式安装最新的开发版本:
cargo install --git https://github.com/medialab/xan --locked
Scoop (Windows)
可以使用 Scoop(https://scoop.sh/)在 Windows 上安装 xan:
scoop bucket add extras
scoop install xan
Homebrew (macOS)
可以使用 Homebrew(https://brew.sh/)在 macOS 上安装 xan,方法如下:
brew install xan
Arch Linux
你可以使用 pacman 从 extra 仓库(https://archlinux.org/packages/extra/x86_64/xan/)安装 xan:
sudo pacman -S xan
NetBSD
官方仓库中提供了一个软件包。要安装 xan,只需运行:
pkgin install xan
Nix
xan 为 Nix 打包,自 25.05 版本起可在 Nixpkgs 中获得。要安装它,你可以将其作为 pkgs.xan 添加到 environment.systemPackages 中,或使用 nix-shell 进入临时 shell。
nix-shell -p xan
Pixi (Linux, macOS, Windows)
可以在 Linux、macOS 和 Windows 上使用 Pixi(https://pixi.sh/latest/)包管理器安装 xan:
pixi global install xan
Conda Forge
可以通过 conda-forge(https://conda-forge.org/)安装 xan,方法如下:
conda install conda-forge::xan
预构建的二进制文件
预构建的二进制文件可以附加到每个 GitHub 发行版(https://github.com/medialab/xan/releases/latest)中找到。当前支持的目标包括:
x86_64-apple-darwinx86_64-unknown-linux-gnux86_64-unknown-linux-muslx86_64-pc-windows-msvcaarch64-apple-darwinaarch64-unknown-linux-gnu
CI 尚未构建 ppc64le 目标,但如果需要,仍然可以在 conda-forge 软件包的文件(https://anaconda.org/conda-forge/xan/files)中找到预构建的二进制文件。欢迎提交 PR 以通过添加相关目标来改进 CI。
安装补全
请注意,xan 还提供了方便的命令和头部/列名称的自动补全,你可以通过 xan completions 命令安装。运行以下命令了解如何安装这些补全:
xan completions -h
对于 zsh,你可以将补全文件添加到 ~/.zfunc:
mkdir -p ~/.zfunc
xan completions zsh > ~/.zfunc/_xan
然后在 ~/.zshrc 中的 compinit 之前添加以下内容:
fpath=(~/.zfunc $fpath)
autoload -Uz compinit
compinit
快速入门
让我们通过探索一个法国媒体语料库来了解最常用的 xan 命令:
下载语料库
curl -LO https://github.com/medialab/corpora/raw/master/polarisation/medias.csv
显示文件的头部
xan headers medias.csv
0 webentity_id
1 name
2 prefixes
3 home_page
4 start_pages
5 indegree
6 hyphe_creation_timestamp
7 hyphe_last_modification_timestamp
8 outreach
9 foundation_year
10 batch
11 edito
12 parody
13 origin
14 digital_native
15 mediacloud_ids
16 wheel_category
17 wheel_subcategory
18 has_paywall
19 inactive
计算行数
xan count medias.csv
478
在终端中预览文件
xan view medias.csv
Displaying 5/20 cols from 10 first rows of medias.csv
┌───┬───────────────┬───────────────┬────────────┬───┬─────────────┬──────────┐
│ - │ name │ prefixes │ home_page │ ... │ has_paywall │ inactive │
├───┼───────────────┼───────────────┼────────────┼───┼─────────────┼──────────┤
│ 0 │ Acrimed.org │ http://acrim...│ http://ww...│ ... │ false │ │
│ 1 │ 24matins.fr │ http://24mat...│ https://w...│ ... │ false │ │
│ 2 │ Actumag.info │ http://actum...│ https://a...│ ... │ false │ │
│ 3 │ 2012un-Nouve...│ http://2012u...│ http://ww...│ ... │ false │ │
│ 4 │ 24heuresactu...│ http://24heu...│ http://24...│ ... │ false │ │
│ 5 │ AgoraVox │ http://agora...│ http://ww...│ ... │ false │ │
│ 6 │ Al-Kanz.org │ http://al-ka...│ https://w...│ ... │ false │ │
│ 7 │ Alalumieredu...│ http://alalu...│ http://al...│ ... │ false │ │
│ 8 │ Allodocteurs...│ http://allod...│ https://w...│ ... │ false │ │
│ 9 │ Alterinfo.net │ http://alter...│ http://ww...│ ... │ │ true │
│ ...│ ... │ ... │ ... │ ... │ ... │ ... │
└───┴───────────────┴───────────────┴────────────┴───┴─────────────┴──────────┘
在 Unix 上,不要犹豫使用 -p 标志来自动将完整输出转发到合适的分页器,并浏览所有列。
读取第一行的扁平化表示
# 注意:使用 -c 以避免截断值
xan flatten -c medias.csv
Row n°0
───────────────────────────────────────────────────────────────────────────────
webentity_id 1
name Acrimed.org
prefixes http://acrimed.org|http://acrimed69.blogspot...
home_page http://www.acrimed.org
start_pages http://acrimed.org|http://acrimed69.blogspot...
indegree 61
hyphe_creation_timestamp 1560347020330
hyphe_last_modification_timestamp 1560526005389
outreach nationale
foundation_year 2002
batch 1
edito media
parody false
origin france
digital_native true
mediacloud_ids 258269
wheel_category Opinion Journalism
wheel_subcategory Left Wing
has_paywall false
inactive
Row n°1
───────────────────────────────────────────────────────────────────────────────
webentity_id 2
...
搜索行
xan search -s outreach internationale medias.csv | xan view
Displaying 4/20 cols from 10 first rows of
┌───┬──────────────┬────────────────────┬───┬─────────────┬──────────┐
│ - │ webentity_id │ name │ ... │ has_paywall │ inactive │
├───┼──────────────┼────────────────────┼───┼─────────────┼──────────┤
│ 0 │ 25 │ Businessinsider.fr │ ... │ false │ │
│ 1 │ 59 │ Europe-Israel.org │ ... │ false │ │
│ 2 │ 66 │ France 24 │ ... │ false │ │
│ 3 │ 220 │ RFI │ ... │ false │ │
│ 4 │ 231 │ fr.Sott.net │ ... │ false │ │
│ 5 │ 246 │ Voltairenet.org │ ... │ true │ │
│ 6 │ 254 │ Afp.com /fr │ ... │ false │ │
│ 7 │ 265 │ Euronews FR │ ... │ false │ │
│ 8 │ 333 │ Arte.tv │ ... │ false │ │
│ 9 │ 341 │ I24News.tv │ ... │ false │ │
│ ...│ ... │ ... │ ... │ ... │ ... │
└───┴──────────────┴────────────────────┴───┴─────────────┴──────────┘
选择某些列
xan select foundation_year,name medias.csv | xan view
Displaying 2 cols from 10 first rows of
┌───┬─────────────────┬───────────────────────────────────────┐
│ - │ foundation_year │ name │
├───┼─────────────────┼───────────────────────────────────────┤
│ 0 │ 2002 │ Acrimed.org │
│ 1 │ 2006 │ 24matins.fr │
│ 2 │ 2013 │ Actumag.info │
│ 3 │ 2012 │ 2012un-Nouveau-Paradigme.com │
│ 4 │ 2010 │ 24heuresactu.com │
│ 5 │ 2005 │ AgoraVox │
│ 6 │ 2008 │ Al-Kanz.org │
│ 7 │ 2012 │ Alalumieredunouveaumonde.blogspot.com │
│ 8 │ 2005 │ Allodocteurs.fr │
│ 9 │ 2005 │ Alterinfo.net │
│ ...│ ... │ ... │
└───┴─────────────────┴───────────────────────────────────────┘
排序文件
xan sort -s foundation_year medias.csv | xan view -s name,foundation_year
Displaying 2 cols from 10 first rows of
┌───┬────────────────────────────────────┬─────────────────┐
│ - │ name │ foundation_year │
├───┼────────────────────────────────────┼─────────────────┤
│ 0 │ Le Monde Numérique (Ouest France) │ │
│ 1 │ Le Figaro │ 1826 │
│ 2 │ Le journal de Saône-et-Loire │ 1826 │
│ 3 │ L'Indépendant │ 1846 │
│ 4 │ Le Progrès │ 1859 │
│ 5 │ La Dépêche du Midi │ 1870 │
│ 6 │ Le Pélerin │ 1873 │
│ 7 │ Dernières Nouvelles d'Alsace (DNA) │ 1877 │
│ 8 │ La Croix │ 1883 │
│ 9 │ Le Chasseur Francais │ 1885 │
│ ...│ ... │ ... │
└───┴────────────────────────────────────┴─────────────────┘
根据某些列去重文件
# 我们语料库中的一些媒体在 mediacloud.org 上具有相同的 ID
xan dedup -s mediacloud_ids medias.csv | xan count && xan count medias.csv
457
478
去重也可以在排序时进行:
xan sort -s mediacloud_ids -u medias.csv
计算频率表
xan frequency -s edito medias.csv | xan view
Displaying 3 cols from 5 rows of
┌───┬───────┬────────────┬───────┐
│ - │ field │ value │ count │
├───┼───────┼────────────┼───────┤
│ 0 │ edito │ media │ 423 │
│ 1 │ edito │ individu │ 30 │
│ 2 │ edito │ plateforme │ 14 │
│ 3 │ edito │ agrégateur │ 10 │
│ 4 │ edito │ agence │ 1 │
└───┴───────┴────────────┴───────┘
打印直方图
xan frequency -s edito medias.csv | xan hist
Histogram for edito (bars: 5, sum: 478, max: 423):
media |423 88.49%|━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━|
individu | 30 6.28%|━━━╸ |
plateforme | 14 2.93%|━╸ |
agrégateur | 10 2.09%|━╸ |
agence | 1 0.21%|╸ |
计算描述性统计
xan stats -s indegree,edito medias.csv | xan transpose | xan view -I
Displaying 2 cols from 14 rows of
┌─────────────┬───────────────────┬────────────┐
│ field │ indegree │ edito │
├─────────────┼───────────────────┼────────────┤
│ count │ 463 │ 478 │
│ count_empty │ 15 │ 0 │
│ type │ int │ string │
│ types │ int|empty │ string │
│ sum │ 25987 │ │
│ mean │ 56.12742980561554 │ │
│ variance │ 4234.530197929737 │ │
│ stddev │ 65.07326792108829 │ │
│ min │ 0 │ │
│ max │ 424 │ │
│ lex_first │ 0 │ agence │
│ lex_last │ 99 │ plateforme │
│ min_length │ 0 │ 5 │
│ max_length │ 3 │ 11 │
└─────────────┴───────────────────┴────────────┘
评估表达式以过滤文件
xan filter 'batch > 1' medias.csv | xan count
130
要访问表达式语言的速查表,请运行 xan help cheatsheet。要显示可用函数的完整列表,请运行 xan help functions。
评估表达式以基于其他列创建新列
xan map 'fmt("{} ({})", name, foundation_year) as key' medias.csv | xan select key | xan slice -l 10
key
Acrimed.org (2002)
24matins.fr (2006)
Actumag.info (2013)
2012un-Nouveau-Paradigme.com (2012)
24heuresactu.com (2010)
AgoraVox (2005)
Al-Kanz.org (2008)
Alalumieredunouveaumonde.blogspot.com (2012)
Allodocteurs.fr (2005)
Alterinfo.net (2005)
要访问表达式语言的速查表,请运行 xan help cheatsheet。要显示可用函数的完整列表,请运行 xan help functions。
通过评估表达式转换列
xan transform name 'split(name, ".") | first | upper' medias.csv | xan select name | xan slice -l 10
name
ACRIMED
24MATINS
ACTUMAG
2012UN-NOUVEAU-PARADIGME
24HEURESACTU
AGORAVOX
AL-KANZ
ALALUMIEREDUNOUVEAUMONDE
ALLODOCTEURS
ALTERINFO
要访问表达式语言的速查表,请运行 xan help cheatsheet。要显示可用函数的完整列表,请运行 xan help functions。
执行自定义聚合
xan agg 'sum(indegree) as total_indegree, mean(indegree) as mean_indegree' medias.csv | xan view -I
Displaying 1 col from 1 rows of
┌────────────────┬───────────────────┐
│ total_indegree │ mean_indegree │
├────────────────┼───────────────────┤
│ 25987 │ 56.12742980561554 │
└────────────────┴───────────────────┘
要访问表达式语言的速查表,请运行 xan help cheatsheet。要显示可用函数的完整列表,请运行 xan help functions。
最后,要显示可用聚合函数的完整列表,请运行 xan help aggregations。
数据绘图
重要提示:当在终端中使用 xan 的命令(如 hist、scatter、correlation、parallel、series、small-multiples、view-grid)时,图表是渲染在 Unicode 点上的。因此,如果终端中的 Unicode 字形字体配置不佳,可能会显得很奇怪。xan 会尽力检测这一点,如果兼容性问题被检测到,可能会退回到一个简单的 ASCII 后备方案(使用 hist 时,使用 -a 标志以 ASCII 模式运行;其他命令也有 -a 标志)。请注意,在 Windows 上,PowerShell 可能需要修补字体支持。
xan scatter foundation_year indegree medias.csv
Scatterplot for foundation_year vs indegree
424 │ ║
│ ║ ║ ║
│ ║ ║ ║ ║
│ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
0 │ ──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──║──
1826 2018 (N=463)
请注意,在上面的散点图中,xan 添加了一个相关性的视觉提示:点的四个象限中的对角线点形成的形状可以让你大致了解相关性的方向和趋势(包括缺失值)。
有关更多信息,你可以阅读专用文档:docs/moonblade/plotting.md
使用小倍数绘制多个图形
xan 还有一个 small-multiples 命令,可以将一个绘图命令应用于数据的一个分组,并将结果渲染为小倍数网格。该命令可用作 xan small-multiples -g column command args,其中 command 是 xan 的另一个绘图命令。
以下是一个示例,按基础绘制年份分组显示 indegree 的直方图:
xan small-multiples -g foundation_year hist indegree medias.csv
Small multiples for foundation_year
╔══════════════════════════════════════════╦══════════════════════════════════════════╦══════════════════════════════════════════╗
║ 1826-1859 (N=3) ║ 1870-1900 (N=9) ║ 1905-1930 (N=2) ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ 422 ║
║ ║ ║ 424 (6) ║
║ ║ ║ 426 ║
║ ║ ║ 422⇌426 (3) ║
╠══════════════════════════════════════════╬══════════════════════════════════════════╬══════════════════════════════════════════╣
║ 1944-1967 (N=9) ║ 1972-1989 (N=10) ║ 1990-1995 (N=9) ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
╠══════════════════════════════════════════╬══════════════════════════════════════════╬══════════════════════════════════════════╣
║ 1996-1997 (N=10) ║ 1998 (N=9) ║ 1999 (N=12) ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║ ║ ║
║ ║
相似文章
@QingQ77: 一个用 Rust 写的命令行 CSV 处理工具("CSV 魔术师"),能极快、低内存地处理上 GB 的 CSV,并自带表达式语言、终端可视化以及词典统计、图论乃至抓取等社科向扩展。 https://github.com/medialab/…
一个用 Rust 编写的命令行 CSV 处理工具 'xan',能够快速、低内存地处理大型 CSV 文件,并自带表达式语言、终端可视化和社科分析扩展。
@ai_suxiaole: 终端里最不缺的就是数字 真正缺的是一眼就能看懂趋势 GitHub 上有个 chartli 小工具,可以直接把命令行输出的数据渲染成图表 不管是服务器监控、日志分析还是脚本统计,只需要一条命令,就能生成 ASCII 折线图、柱状图、热力图、…
介绍一个名为 chartli 的命令行工具,可以将命令行输出的数字数据直接渲染成 ASCII 图表(折线图、柱状图、热力图等),支持管道输入、文件读取和多种图表类型,适合服务器监控、日志分析等场景。
Tsplat – 在终端中运行高斯泼溅渲染
Tsplat 是一款基于 Rust 的命令行工具,仅使用 CPU 即可直接在终端中渲染 3D 高斯泼溅场景,甚至支持通过 SSH 运行。它支持 Unicode 半角块和图形协议,并具有导航和自动旋转控制。
@PrajwalTomar_: 等等,这简直太疯狂了。你知道图表在应用或笔记本处理真实数据时就开始卡顿和延迟吗?
Reflex 开源了 xy,这是一个用 Rust 构建的高性能 Python 图表库,仅通过绘制可见点就能在 5.4 毫秒内渲染 1000 万个数据点,可直接替代 Matplotlib、Plotly 和 Bokeh。
@tom_doerr: 轻松打开巨大CSV文件,能在Mac Mini M2上32秒内加载1600万行。https://github.co…
Tablecruncher,一款极速CSV编辑器,已在GPL v3下开源,能在M2 Mac Mini上32秒内加载1600万行。