Rerun DataFrame 查询入门:用 Python 从 RRD 录制中提取前 10 行数据并支持实体路径过滤
2026/9/16 21:20:42 网站建设 项目流程

Rerun DataFrame 查询入门:用 Python 从 RRD 录制中提取前 10 行数据并支持实体路径过滤

【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun

本文是 Rerun 开源仓库中 examples/python/dataframe_query 示例的完整技术指南。你将学会如何通过rerun.server.Server在本地启动一个 Rerun 服务、加载任意.rrd录制文件,再借助 DataFrame API(底层基于 DataFusion)以表格形式在终端中查询并展示数据的前 10 行,同时掌握实体路径过滤表达式(如/helix/structure/**)的写法与底层实现原理。读完本文后,你既能直接运行示例脚本,也能把这套"服务端过滤 + DataFrame 读取"的查询范式迁移到自己的数据处理流程中。

一、示例定位:终端里的 DataFrame 查询

dataframe_query是 Rerun 仓库中用于演示 DataFrame API 基础用法的 Python 示例。它的目标非常聚焦:打开一个 Rerun 录制文件(.rrd),查询其中的数据,并把前 10 行以表格形式打印到终端

该示例的完整代码位于 examples/python/dataframe_query/dataframe_query.py,核心执行逻辑只有约 30 行,非常适合作为理解 Rerun 数据查询 API 的入门入口。其依赖声明在 examples/python/dataframe_query/pyproject.toml 中,唯一的运行时依赖是rerun-sdk,且同时将dataframe_query注册为可执行脚本入口(dataframe_query = "dataframe_query:main"),安装后即可直接用命令调用。

examples/python/dataframe_query/ ├── README.md # 示例说明文档 ├── dataframe_query.py # 示例主脚本 └── pyproject.toml # 项目配置与依赖声明

示例的完整调用形式如下:

python dataframe_query.py <path_to_rrd> [entity_path_filter]

其中第一个参数path_to_rrd是必填的 RRD 文件路径,第二个可选参数entity_path_filter是实体路径过滤表达式,默认为/**(匹配所有实体)。

二、获取测试数据:下载官方托管示例录制

如果没有现成的 Rerun 录制文件,可以从 Rerun 官方托管的示例中下载一个。例如下载dna(DNA 双螺旋结构)示例的录制:

curl 'https://app.rerun.io/version/latest/examples/dna.rrd' -o - > /tmp/dna.rrd

这条命令通过 curl 把远程 RRD 文件直接写入本地/tmp/dna.rrddna示例包含/helix/structure等实体路径,非常适合用来测试实体路径过滤功能。

当然,也可以使用你自己通过rr.log系列 API 生成或从其他途径获得的任意 RRD 文件。仓库的 tests/assets/rrd 目录下也存放着大量可用于测试的.rrd录制文件。

三、运行示例:两种典型用法

3.1 查询全部数据的前 10 行

直接指定录制文件路径,不传过滤表达式(此时默认匹配所有实体):

python dataframe_query.py /tmp/dna.rrd

脚本会启动本地服务、加载录制、读取全部实体的数据,并将结果以 pandas 表格形式打印前 10 行。

3.2 按实体路径过滤后查询

第二个参数用于指定实体路径过滤表达式,只查询匹配的实体子树。例如只查看 DNA 示例中helix/structure子树下的数据:

python dataframe_query.py my_recording.rrd /helix/structure/**

注意在 Shell 中,**有被路径通配展开的风险,因此建议像文档示例那样对表达式加引号,或直接在字符串参数中使用转义,确保过滤表达式原样传给脚本。例如:

python dataframe_query.py my_recording.rrd '/helix/structure/**'

四、代码逐段拆解:三步完成查询

dataframe_query.py 的query()函数完整呈现了 Rerun DataFrame 查询的经典三步流程:

def query(path_to_rrd: str, entity_path_filter: str) -> None: with rr.server.Server(datasets={"recording": [path_to_rrd]}) as server: dataset = server.client().get_dataset("recording") # Query the data view = dataset.filter_contents([entity_path_filter]) df = view.reader(index="log_time") # Convert to pandas and show first 10 rows table = df.to_pandas() print(table.head(10))

4.1 第一步:启动本地 Server 并注册数据集

with rr.server.Server(datasets={"recording": [path_to_rrd]}) as server:

rr.server.Server是 Rerun SDK 提供的服务端类,位于 rerun_py/rerun_sdk/rerun/server.py,它"托管录制并通过 HTTP 提供服务,客户端连接后可访问 catalog(数据目录)"。作为上下文管理器使用时,退出with块会自动关闭服务,无需手动清理。

构造函数的datasets参数是一个字典,键为数据集名称,值为路径。从源码(server.py第 48-122 行)可以看到其取值规则:

  • 单一路径(str/PathLike):必须是目录,启动时会把目录内所有 RRD 文件都注册为该数据集;
  • 路径序列(list):每个路径必须是一个 RRD 文件,全部注册为该数据集。

示例中datasets={"recording": [path_to_rrd]}传入的是单文件列表,因此recording数据集只包含这一个录制。

其他值得了解的参数:host(默认0.0.0.0,绑定所有网卡,便于从其他机器连接查看器)、port(默认None/0,由操作系统随机分配空闲端口,可通过server.url()获取实际地址)、tables(可选,加载 Lance 表文件)。此外 SDK 还提供了server.client()获取连接本服务的 CatalogClient、server.is_running()检查服务状态、server.shutdown()手动关闭等接口。

4.2 第二步:获取数据集并构建过滤视图

dataset = server.client().get_dataset("recording") view = dataset.filter_contents([entity_path_filter])

server.client()返回一个 CatalogClient(需要安装datafusion包,否则初始化会报错),get_dataset("recording")按名称取回刚注册的数据集DatasetEntry

随后调用DatasetEntry.filter_contents()得到DatasetView。根据 rerun_py/rerun_sdk/rerun/catalog/_entry.py 中的源码注释,DatasetView是对数据集"分段与实体路径的惰性过滤视图",过滤条件会延迟组合,直到真正读取数据时才生效——这意味着构建视图本身开销很低,可以放心地链式叠加多个过滤条件。

4.3 第三步:以 log_time 为索引读取 DataFrame

df = view.reader(index="log_time") table = df.to_pandas() print(table.head(10))

view.reader(index="log_time")返回一个DataFusion DataFrame,并以名为log_time的时间轴(timeline)作为行索引。随后to_pandas()将其转换为 pandas DataFrame,head(10)只显示前 10 行。

需要说明的是:log_time只是该示例选用的索引,实际索引名取决于录制中注册的时间轴(timeline),常见的时间轴还有real_time等。可以按自己的数据选择对应的索引名,如view.reader(index="real_time")

reader()还支持更多进阶参数(详见_entry.py第 763-857 行与第 1028-1139 行):

  • index=None:只读取静态数据(无时间索引的数据);
  • include_semantically_empty_columns:是否包含语义上为空的列;
  • include_tombstone_columns:是否包含"墓碑"(删除标记)列;
  • fill_latest_at:是否用最近的有效值填充 null;
  • using_index_values:指定索引值集合进行重采样,此时每个(segment, index_value)组合返回一行;支持数组、字典(按 segment ID 映射)或 DataFrame 三种形式。

4.4 命令行入口

main()使用标准库argparse解析两个位置参数:

parser.add_argument("path_to_rrd", type=str, help="Path to the .rrd file") parser.add_argument( "entity_path_filter", type=str, nargs="?", default="/**", help="Optional entity path filter expression", )

entity_path_filter通过nargs="?"设为可选,缺省值为/**(匹配全部实体)。同时pyproject.toml中注册了dataframe_query控制台脚本,因此安装示例后也可以直接运行dataframe_query /tmp/dna.rrd

五、实体路径过滤表达式详解

5.1 表达式语法

实体路径过滤表达式以/开头,支持通配符**。按 rerun_py/rerun_sdk/rerun/catalog/_content_filter.py 与_entry.py中的文档:

  • "/points/**":匹配/points下的所有实体;
  • "-/text/**":排除/text下的所有实体(前缀-表示排除);
  • 多个表达式可组合成列表传入,如["/points/**", "-/text/**"]表示"包含/points/**且排除/text/**";
  • 传入空列表[]表示过滤掉全部内容。

传入字符串时会自动包装成单元素列表(见_entry.py第 756-761 行),所以单表达式和列表两种写法等价。

5.2 ContentFilter 流式构建器

除了裸字符串,filter_contents()还接受ContentFilter对象。它是不变(immutable)的流式构建器,从everything()(等价于"/**",默认自动排除__properties子树)或nothing()(等价于空列表)出发,链式调用:

  • .include(path, subtree=False):包含匹配路径的实体,subtree=True时自动追加/**
  • .exclude(path, subtree=False):排除匹配路径的实体,生成带-前缀的表达式;
  • .include_properties():把默认自动排除的__properties/**子树重新包含进来。

例如:

from rerun.catalog import ContentFilter # 排除原始机器人数据,但保留其中一条特定路径 view = dataset.filter_contents( ContentFilter.everything() .exclude("/robot/raw/**") .include("/robot/raw/i_need_this") ) # 从"什么都不含"开始,只允许指定子树 view = dataset.filter_contents( ContentFilter.nothing() .include("/points", subtree=True) .include("/world/camera") )

_build_path_expr_content_filter.py第 4-9 行)会校验路径必须以/开头,并在需要时自动追加/**。对于路径片段中包含空格、感叹号等特殊字符的实体,还可以用include_path/exclude_path按路径片段列表传入,实现自动转义。

六、底层原理:服务端过滤与 DataFusion

示例中filter_contents(...)reader(index=...)的组合,背后是 Rerun 的数据查询架构:

惰性视图filter_contents返回的DatasetView只是记录了过滤表达式,并不立即读取数据(见_entry.py第 900-926 行的类文档"Filters are composed lazily and only applied when data is actually read")。

DataFusion 即所得reader()直接返回 DataFusion 的datafusion.DataFrame,因此view.reader(...)的结果天然支持 DataFusion 的全部能力——filterselectjoin、聚合等都可以继续链式调用,最后再to_pandas()落入本地。

服务端下推过滤_entry.pyreader()DatasetView.reader()的文档明确说明,返回的 DataFrame 对rerun_segment_id和索引列(timeline)的过滤会在 Rerun 服务端执行,可显著提升性能。例如:

from datafusion import col, lit # 按 segment 过滤(服务端执行) dataset.reader(index="real_time").filter(col("rerun_segment_id") == "aabbccddee") # 按时间窗口过滤(服务端执行) df = dataset.reader(index="real_time").filter( (col("real_time") >= lit(t0)) & (col("real_time") <= lit(t1)) )

换句话说,"实体路径过滤 + 分段过滤 + 索引范围过滤"这类重活可以在服务端完成,客户端只接收精简后的结果,这正是大数据量下保持查询效率的关键。

七、运行前提与环境说明

  • Python 版本pyproject.toml中被注释掉的requires-python = "<3.12"提示该示例预期在 Python 3.12 以下版本运行,若使用更高版本可能需要按当前 SDK 的约束调整;
  • 依赖:需要rerun-sdk,运行client()还需要datafusion包;
  • 数据:需要准备一个.rrd录制文件(本地录制或按上文 curl 下载均可);
  • 过滤表达式:Shell 中注意对**加引号防止被通配展开。

八、进一步探索

如果想把这个示例扩展到更复杂的场景,可以从仓库中找到大量现成材料:

  • 完整 DataFrame 查询 API:DatasetEntryDatasetView的全部方法(filter_segmentssegment_tableget_index_rangesschemaarrow_schema等)见 rerun_py/rerun_sdk/rerun/catalog/_entry.py;
  • 服务端实现与数据集管理:Rust 侧相关逻辑集中在 crates/store_app/re_server;
  • 更多查询用例:Python 端集成测试位于 rerun_py/tests/e2e_redap_tests,其中包含大量针对 catalog / dataframe 查询链路的断言用例,可对照学习参数边界与预期行为。

至此,你已经掌握了从"启动本地服务、注册 RRD、按实体路径过滤、按时间轴读取 DataFrame、输出表格"的完整查询链路,可以直接把该模式复用到自己的录制数据处理与调试流程中。

【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询