You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用同一字典映射Polars数据框的两列节点至索引

Polars优雅实现节点到索引的映射

数据准备

我有一个描述网络连接的Polars数据框,记录节点间的连接权重:

import polars as pl
df_network = pl.DataFrame(
    {"node1": ["a", "c", "c"], "node2": ["b", "d", "a"], "weight": [1, 2, 3]}
)
# shape: (3, 3)
# ┌───────┬───────┬────────┐
# │ node1 ┆ node2 ┆ weight │
# │ ---   ┆ ---   ┆ ---    │
# │ str   ┆ str   ┆ i64    │
# ╞═══════╪═══════╪════════╡
# │ a     ┆ b     ┆ 1      │
# │ c     ┆ d     ┆ 2      │
# │ c     ┆ a     ┆ 3      │
# └───────┴───────┴────────┘

另有一个节点到整数索引的映射数据框:

df_node_index = pl.DataFrame({"node": ["d", "b", "c", "a"], "index": [0, 1, 2, 3]})
# shape: (4, 2)
# ┌──────┬───────┐
# │ node ┆ index │
# │ ---  ┆ ---   │
# │ str  ┆ i64   │
# ╞══════╪═══════╡
# │ d    ┆ 0     │
# │ b    ┆ 1     │
# │ c    ┆ 2     │
# │ a    ┆ 3     │
# └──────┴───────┘

需要将node1和node2替换为对应的索引值,得到目标数据框:

df_desirable = pl.DataFrame({"index1": [3, 2, 2], "index2": [1, 0, 3], "weight":[1,2,3]})
# shape: (3, 3)
# ┌────────┬────────┬────────┐
# │ index1 ┆ index2 ┆ weight │
# │ ---    ┆ ---    ┆ ---    │
# │ i64    ┆ i64    ┆ i64    │
# ╞════════╪════════╪════════╡
# │ 3      ┆ 1      ┆ 1      │
# │ 2      ┆ 0      ┆ 2      │
# │ 2      ┆ 3      ┆ 3      │
# └────────┴────────┴────────┘

当前实现方案

我目前通过两次join实现需求,虽然可行但不够简洁:

df_network.join(
    df_node_index.rename({"index": "index1"}),
    how="left",
    left_on="node1",
    right_on="node",
).join(
    df_node_index.rename({"index": "index2"}),
    how="left",
    left_on="node2",
    right_on="node",
).select(
    ["index1", "index2", "weight"]
).equals(df_desirable) # True

更优雅的Polars实现方案

方案1:使用lookup方法(原生高效)

Polars的lookup方法可以直接在列上执行映射查询,无需多次join,代码更简洁且性能更优:

result = df_network.with_columns(
    index1=pl.col("node1").lookup(df_node_index, "node", "index"),
    index2=pl.col("node2").lookup(df_node_index, "node", "index")
).drop("node1", "node2")

print(result.equals(df_desirable)) # True

方案2:使用字典映射(简洁直观)

先将映射数据框转换为Python字典,再用map_dict方法替换列值,适合小数据集场景:

# 构建节点到索引的字典
node_map = df_node_index.select(pl.col("node"), pl.col("index")).to_dict(as_series=False)
node_map = dict(zip(node_map["node"], node_map["index"]))

result = df_network.with_columns(
    index1=pl.col("node1").map_dict(node_map),
    index2=pl.col("node2").map_dict(node_map)
).drop("node1", "node2")

print(result.equals(df_desirable)) # True

内容的提问来源于stack exchange,提问作者TomNorway

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 13:29:59