
marimo 交互式表格组件 mo.ui.table 完全指南数据绑定、行/单元格选择、分页与高级格式化【免费下载链接】marimoA reactive notebook for Python — run reproducible experiments, query with SQL, execute as a script, deploy as an app, and version with git. Stored as pure Python. All in a modern, AI-native editor.项目地址: https://gitcode.com/GitHub_Trending/ma/marimo本文是 marimo 响应式笔记本中mo.ui.table交互式表格组件的完整技术指南。该组件把静态 DataFrame 变成可搜索、可排序、可筛选、可多选、可下载的数据交互界面其选中结果会以table.value的形式响应式驱动下游单元格广泛适用于数据探索、仪表盘搭建与数据清洗场景。读完本文你将掌握mo.ui.table的全部数据输入格式、选择模式、分页机制、列管理与条件格式化技巧并能基于源码理解其底层搜索/下载/统计管道的实现原理。一、组件定位从展示数据到交互数据mo.ui.table是 marimo UI 插件体系marimo/_plugins/ui/_impl/table.py中面向表格数据的核心交互组件。与只读的数据展示不同它是一个UIElement子类具备两大能力交互性用户可以在浏览器中对表格执行搜索、排序、筛选、分页、选择行/单元格等操作响应式任何选择都会实时同步到 Python 端的table.value从而驱动依赖它的单元格自动重算实现操作表格即操作数据的响应式编程范式。从源码类型签名看marimo/_plugins/ui/_impl/table.py组件的value类型是list[JSONType] | IntoDataFrame | list[TableCell]即选中内容会尽量保持与输入数据相同的格式返回——输入是 DataFrame 则返回 DataFrame输入是字典列表则返回字典列表。二、快速上手原文档示例完整还原docs/api/inputs/table.md中给出了一个基于office_characters人物数据的完整示例其核心结构如下可直接在 marimo 笔记本中运行import marimo as mo # 1. 创建表格20 行人物数据开启分页 table mo.ui.table(dataoffice_characters, paginationTrue) # 2. 将表格组件与其选中值并排展示 mo.vstack([table, table.value])其中office_characters是{first_name: ..., last_name: ...}形式的字典列表共 20 条记录Michael Scott、Jim Halpert、Dwight Schrute 等。这段代码揭示了两个最核心的使用要点paginationTrue开启分页当数据行数较多时分页避免一次性渲染全部行保证界面流畅mo.vstack([table, table.value])展示选中结果table.value在未选择任何行时返回空值一旦用户勾选行下方区域会立即显示选中的子集——这正是mo.ui.table响应式能力的直观体现。三、四种数据输入格式mo.ui.table的data参数非常灵活源码 docstringtable.py明确支持以下四种形态1. 字典列表每行一个 dict最直观table mo.ui.table( data[ {first_name: Michael, last_name: Scott}, {first_name: Dwight, last_name: Schrute}, ], labelUsers, )2. 值列表单列表格table mo.ui.table( data[Michael Scott, Dwight Schrute], labelUsers, )3. 列表字典每列一个 listtable mo.ui.table( data{ first_name: [Michael, Dwight], last_name: [Scott, Schrute], }, labelUsers, )4. DataFrame 与惰性数据源# df 可以是 Pandas 或 Polars 的 DataFrame table mo.ui.table( datadf, paginationTrue, # 行数多时建议显式开启分页 labelDataframe, )从源码看data的完整类型为ListOrTuple[primitive | MIME | None] | ListOrTuple[dict] | dict[str, ListOrTuple[JSONType]] | IntoDataFrame | IntoLazyFrametable.py其中原始值支持str、int、float、bool、None还支持marimo 元素作为单元格值例如mo.ui.button(...)、mo.md(...)、mo.as_html(...)即表格单元格本身可以嵌入其他交互组件DataFrame 支持 Pandas、Polars、PyArrow、Ibis、DuckDB 等 narwhals 生态的数据源。data参数还接受惰性数据帧Polars LazyFrame、Ibis Table、DuckDB Relation需要配合table.lazy()使用详见第七节。四、读取选中值table.value与table.datamo.ui.table暴露两个关键属性table.py属性含义返回值table.value用户当前选中的行/单元格与输入数据同格式的子集无选择时为Nonetable.data传入的原始数据保持原始格式list / dict / DataFramevalue的具体形态取决于selection模式行选择模式single/multi返回选中的行格式与输入数据一致单元格选择模式single-cell/multi-cell返回TableCell列表每个TableCell是(row, column, value)命名的元组table_manager.pyselectionNone禁用选择value恒为None。底层实现通过_convert_value完成前后端数据的转换table.py行选择模式下组件从搜索/筛选后的数据集中按行号取子集若存在稳定的行 IDDataFrame 输入时会注入_marimo_row_id索引列则跨原始数据定位行并在返回前剔除该内部索引列保证用户拿到的数据干干净净。五、分页、页大小与显示控制5.1 分页开关与页大小table mo.ui.table(datadf, paginationTrue, page_size10)参数行为源码第 491-492、497 行的 docstring 与__init__逻辑pagination是否分页。默认值为None时自动决策——当总行数超过page_size默认 10或行数未知too_many时自动开启分页否则关闭paginationFalse时全部行一次性渲染page_size每页行数默认 10由 marimo 配置项default_table_page_size决定见第七节max_height表格体的最大像素高度设置后表格内部纵向滚动且表头粘滞sticky方便浏览长表。5.2 界面元素开关show_*参数mo.ui.table提供一组布尔参数精细控制界面元素源码 docstring table.py参数默认值说明show_searchTrue是否显示搜索框show_downloadTrueDataFrame 输入是否显示下载按钮show_column_summaries见下方是否显示列统计摘要直方图/统计show_data_typesTrue是否在表头显示列数据类型指示show_column_summaries接受bool | stats | chart三态True同时显示统计与图表stats只显示统计chart只显示图表。其默认值由源码自动计算table.py当列数 ≤ 40 且行数 ≥ 11或行数未知时为True否则为False对应的内部常量见 table_manager.pyDEFAULT_SUMMARY_CHARTS_COLUMN_LIMIT 40列摘要图表上限DEFAULT_SUMMARY_CHARTS_ROW_LIMIT 20_000列图表行数上限超过则只显示统计不渲染图表保证浏览器性能DEFAULT_SUMMARY_CHARTS_MINIMUM_ROWS 11显示摘要所需的最小行数DEFAULT_SUMMARY_STATS_ROW_LIMIT 1_000_000统计计算行数上限超过则禁用摘要避免拖垮内核。5.3 统一显示配置Display源码中定义了table.Display这个 TypedDict可将多个show_*选项打包复用table.pycfg mo.ui.table.Display(show_searchFalse, show_downloadFalse) mo.ui.table(data, **cfg) # 基于原配置派生变体原配置对象不受影响 mo.ui.table(other, **{**cfg, show_column_summaries: False})六、选择模式与初始选择6.1 四种选择模式selection参数接受None | single | multi | single-cell | multi-cell默认multi# 单选行 t1 mo.ui.table(data, selectionsingle) # 多选行默认 t2 mo.ui.table(data, selectionmulti) # 单选单元格 / 多选单元格 t3 mo.ui.table(data, selectionsingle-cell) t4 mo.ui.table(data, selectionmulti-cell)6.2 初始选择initial_selection# 行选择模式传入行索引列表 table mo.ui.table(data, selectionmulti, initial_selection[0, 2]) # 单元格选择模式传入 (rowId, columnName) 元组列表 table mo.ui.table(data, selectionmulti-cell, initial_selection[(0, a), (1, b)])源码对initial_selection做了严格校验table.py单选模式single/single-cell下传入超过一个索引会抛出ValueError单元格模式下元素必须是长度为 2 的元组否则抛TypeError索引越界会抛IndexError提示 initial_selection contains invalid row indices。这些约束在测试文件 tests/_plugins/ui/_impl/test_table.py 中都有对应用例如selectionsingle配initial_selection[0, 1]必须报错。注意测试中还验证了排序/搜索后再选择的正确性——value始终基于当前搜索筛选视图计算而非原始数据位置test_table.py。七、懒加载mo.ui.table.lazy()与大数据集对于 Polars LazyFrame、Ibis Table、DuckDB Relation 等惰性数据源mo.ui.table.lazy()提供按需加载的能力table.py# df 是 Polars LazyFrame / Ibis Table / DuckDB Relation table mo.ui.table.lazy(df, page_size10, preloadFalse)关键特性不会立即把数据载入内存直到用户请求才加载且首次只加载前 10 行page_size可调preloadFalse默认时用户需点击确认后才加载首页数据避免意外触发昂贵查询懒加载表格不支持分页与行选择内部强制paginationFalse, selectionNone并自动关闭列摘要与下载界面显示 Previewing only the first N rows. 提示横幅传入非惰性数据源会抛出ValueError提示必须是 Polars LazyFrame、Ibis Table 或 DuckDB Relation。该能力对连接数亿行的数据库表、Parquet 大文件等场景尤其重要可以让笔记本先看结构再按需拉取。八、列管理可见性、冻结、宽度与表头mo.ui.table提供了一组精细的列级控制参数并在__init__中通过独立的_validate_*函数做前置校验table.py8.1 显示与隐藏# 方式一显式指定要隐藏的列 table mo.ui.table(df, hidden_columns[password_hash]) # 方式二只显示指定列其余全部隐藏 table mo.ui.table(df, visible_columns[name, age])hidden_columns与visible_columns互斥同时传入会抛ValueError行索引列row headers始终可见不能被隐藏源码 table.py内部实现上visible_columns会被转换成隐藏列表表头行头之外的所有列并做去重保序处理。8.2 冻结列类似 Excel 冻结窗格table mo.ui.table( df, freeze_columns_left[name], # 左侧冻结横向滚动时始终可见 freeze_columns_right[total], # 右侧冻结 )校验规则_validate_frozen_columnstable.py同一列不能同时冻结在左右两侧冻结列必须真实存在行索引只能冻结在左侧试图把行索引冻结到右侧会报错并提示改用freeze_columns_left。8.3 列宽、换行、对齐与表头提示table mo.ui.table( df, column_widths{name: 200}, # 固定像素列宽 wrapped_columns[description], # 文本换行列 text_justify_columns{age: right}, # 对齐left/center/right header_tooltip{name: 员工姓名}, # 表头悬停提示 )column_widths的值必须是正整数否则抛ValueErrortext_justify_columns只接受left / center / right三个取值未列入column_widths的列按内容自适应宽度以上所有列名参数都会校验列是否存在不存在时抛Column xxx not found in table.。8.4 最大列数max_columnstable mo.ui.table(df, max_columns10) # 最多显示 10 列 table mo.ui.table(df, max_columnsNone) # 显示所有列默认值为inheritMAX_COLUMNS_NOT_PROVIDED即继承配置项default_table_max_columns默认 50见第九节。列数被截断时界面顶部会显示 Only showing N of M columns. 提示横幅。值得注意的是当列被截断时内部仍会保留_marimo_row_id索引列确保筛选后选择行依然准确源码注释 table.py。九、格式化与条件样式9.1format_mapping单元格格式化format_mapping是列名 → 格式化函数或格式字符串的映射table.pydef format_name(name): return name.upper() table mo.ui.table( data[ {first_name: Michael, last_name: Scott, age: 45}, {first_name: Dwight, last_name: Schrute, age: 40}, ], format_mapping{ first_name: format_name, # 可调用对象格式化 age: {:.1f}.format, # 字符串格式等价于 str.format }, )格式化只作用于显示底层同时保存未格式化的原始数据raw_data下载时默认导出未格式化数据避免格式化污染数据本身。9.2style_cell条件单元格样式style_cell接收(rowId, columnName, value)返回 CSS 样式字典table.pyimport random def style_cell(_rowId, _columnName, value): return { backgroundColor: lightcoral if value 4 else cornflowerblue, color: white, fontStyle: italic, } table mo.ui.table( data[random.randint(0, 10) for _ in range(200)], style_cellstyle_cell, )样式按页在 Python 端计算后随搜索结果一起下发前端cell_styles字段单个单元格样式计算失败仅记录警告并降级为空样式不会导致内核崩溃。9.3hover_template单元格悬停提示def hover_cell(rowId, columnName, value): return fRow {rowId} — {columnName}: {value} table mo.ui.table( data[random.randint(0, 10) for _ in range(200)], hover_templatehover_cell, )hover_template支持两种形态字符串模板行级统一模板或可调用对象按单元格逐格计算。可调用对象的返回值仅支持纯文本按页在 Python 端预计算后通过原生 HTMLtitle属性展示。十、底层机制搜索 / 筛选 / 排序 / 下载管道mo.ui.table的前端组件通过Function注册了 8 个内核函数table.pydownload_as、get_column_summaries、search、get_row_ids、get_data_url、calculate_top_k_rows、preview_column、get_size_bytes。理解它们有助于掌握组件的性能边界。10.1 搜索管道query sort filters前端每次交互搜索、排序、筛选、翻页都会调用_searchtable.py内部按以下顺序处理筛选filters递归校验条件树自动剔除指向不存在列的无效条件、对 geometry 列执行过滤的条件、以及运算符与列数据类型不匹配的条件_filter_valid_columnstable.py然后通过apply_transforms_to_df生成过滤后的数据集搜索query调用 TableManager 的search对剩余数据做全文检索排序sort跳过不存在的列与 geometry 列后调用sort_values分页截断按page_size切片并按max_columns截断列。其中筛选、查询、排序的组合结果使用functools.lru_cache缓存_apply_filters_query_sort_cached同一组参数不会重复计算。整个过程对 Polars 等可能抛BaseException的库做了兜底确保异常不会击穿内核。10.2 下载CSV / TSV / JSON / Parquetdownload_as支持四种格式table.py有选中行时下载选中行否则下载当前搜索/筛选视图单元格选择模式不支持下载选中单元格会退化为下载全部数据Parquet 导出对依赖做了预检无 polars 且无 pyarrow 时会返回missing_packages响应前端据此引导用户安装缺失依赖后重试下载文件名自动取变量绑定名get_bound_name。10.3 列统计与图表数据列摘要通过get_column_summaries按需计算table.py逻辑要点统计与图表分别受 100 万行与 2 万行上限约束超限时返回is_disabledTrue让前端显示提示横幅布尔/未知/geometry 列、全空列不渲染图表字符串枚举列计算 value counts含 others 汇总桶与 unique values 特例数值与时间列计算分箱直方图图表数据优先导出为 Arrow IPC内存更省、速度更快依次回退 CSV、JSON并通过 data URL 交给浏览器缓存。十一、全局配置与默认值mo.ui.table的两个默认值来自 marimo 配置文件的display段marimo/_config/config.py配置项默认值作用default_table_page_size10表格默认每页行数default_table_max_columns50表格默认最大显示列数// .marimo.toml 或 marimo 配置中的 display 段 { display: { default_table_page_size: 10, default_table_max_columns: 50 } }对应读取函数get_default_table_page_size与get_default_table_max_columns在运行时从上下文配置中取值table.py。这意味着同一个组件在不同项目/团队配置下可以有不同的默认观感而无需改动代码。十二、边界与最佳实践小结结合源码校验逻辑与测试用例tests/_plugins/ui/_impl/test_table.py使用时需注意行索引row headers不可隐藏、不可冻结在右侧它们始终渲染在左侧hidden_columns与visible_columns互斥单选模式initial_selection只允许一个索引搜索框、筛选、排序都作用于同一份数据管道选择结果是当前视图的子集请勿假定行号与原始数据一致需要跨视图稳定定位时框架内部借助_marimo_row_id保证超过 100 万行且带搜索条件时全选会被拒绝并提示先缩小数据范围源码 table.py大数据集优先考虑mo.ui.table.lazy()或显式开启分页以平衡内存与体验从源码_mime_方法table.py可以看出在非交互环境如 GitHub 静态预览中组件会自动降级为 DataFrame 的原生 HTML 表示不影响文档与静态导出。mo.ui.table把展示与交互合二为一上游任何单元格改变数据表格自动更新用户在表格中的任何操作又通过table.value反哺下游分析逻辑。结合本文介绍的选择模式、列管理、条件样式与懒加载能力你可以在 marimo 中搭建从数据清洗到仪表盘交付的完整交互链路。更完整的 API 说明可查阅 docs/api/inputs/table.md 与官方输入组件索引 docs/api/inputs/index.md更多可运行示例位于 examples/ui/table.py 与 examples/ui/table_advanced.py。【免费下载链接】marimoA reactive notebook for Python — run reproducible experiments, query with SQL, execute as a script, deploy as an app, and version with git. Stored as pure Python. All in a modern, AI-native editor.项目地址: https://gitcode.com/GitHub_Trending/ma/marimo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考