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

如何将Polars中pl.corr结果转为指定格式的相关系数DataFrame?

问题:生成按分组的相关系数矩阵目标格式

现有Polars DataFrame:

import polars as pl

df = pl.DataFrame(
    {
        "group": [1, 1, 1, 1, 2, 2, 2, 2],
        "a": [1, 2, 3, 4, 1, 2, 3, 4],
        "b": [5, 1, 7, 9, 2, 4, 9, 7],
        "c": [2, 6, 3, 9, 1, 5, 3, 6],
    }
)

希望生成按group分组的如下结构的相关系数矩阵DataFrame:

┌───────┬──────┬──────────┬──────────┬──────────┐
│ group ┆ name ┆ a        ┆ b        ┆ c        │
│ ---   ┆ ---  ┆ ---      ┆ ---      ┆ ---      │
│ i64   ┆ str  ┆ f64      ┆ f64      ┆ f64      │
╞═══════╪══════╪══════════╪══════════╪══════════╡
│ 1     ┆ a    ┆ 1.0      ┆ 0.680336 ┆ 0.734847 │
│ 1     ┆ b    ┆ 0.680336 ┆ 1.0      ┆ 0.246885 │
│ 1     ┆ c    ┆ 0.734847 ┆ 0.246885 ┆ 1.0      │
│ 2     ┆ a    ┆ 1.0      ┆ 0.830455 ┆ 0.756889 │
│ 2     ┆ b    ┆ 0.830455 ┆ 1.0      ┆ 0.410983 │
│ 2     ┆ c    ┆ 0.756889 ┆ 0.410983 ┆ 1.0      │
└───────┴──────┴──────────┴──────────┴──────────┘

目前尝试的代码生成了扁平格式结果:

df.group_by("group").agg(
    pl.corr(col1, col2).alias(f"{col1}_{col2}")
    for col1 in ["a", "b", "c"]
    for col2 in ["a", "b", "c"]
)

得到的结果:

shape: (2, 10)
┌───────┬─────┬──────────┬──────────┬───┬──────────┬──────────┬──────────┬─────┐
│ group ┆ a_a ┆ a_b      ┆ a_c      ┆ … ┆ b_c      ┆ c_a      ┆ c_b      ┆ c_c │
│ ---   ┆ --- ┆ ---      ┆ ---      ┆   ┆ ---      ┆ ---      ┆ ---      ┆ --- │
│ i64   ┆ f64 ┆ f64      ┆ f64      ┆   ┆ f64      ┆ f64      ┆ f64      ┆ f64 │
╞═══════╪═════╪══════════╪══════════╪═══╪══════════╪══════════╪══════════╪═════╡
│ 2     ┆ 1.0 ┆ 0.830455 ┆ 0.756889 ┆ … ┆ 0.410983 ┆ 0.756889 ┆ 0.410983 ┆ 1.0 │
│ 1     ┆ 1.0 ┆ 0.680336 ┆ 0.734847 ┆ … ┆ 0.246885 ┆ 0.734847 ┆ 0.246885 ┆ 1.0 │
└───────┴─────┴──────────┴──────────┴───┴──────────┴──────────┴──────────┴─────┘

需要将结果转换为目标格式,或者找到更直接的生成方法。

解决方案

方法一:从扁平结果转换

通过拆分列名、重塑数据结构,将现有扁平结果转换为目标格式:

# 先获取扁平结果
flat_df = df.group_by("group").agg(
    pl.corr(col1, col2).alias(f"{col1}_{col2}")
    for col1 in ["a", "b", "c"]
    for col2 in ["a", "b", "c"]
)

# 转换为目标格式
result = (
    flat_df
    # 将非group列转为长格式:列名作为配对标识,值为相关系数
    .melt(id_vars="group", variable_name="pair", value_name="corr")
    # 拆分配对标识,得到行名和列名
    .with_columns(
        pl.col("pair").str.split("_").list.get(0).alias("name"),
        pl.col("pair").str.split("_").list.get(1).alias("col")
    )
    # 透视数据,将列名转为表头
    .pivot(index=["group", "name"], columns="col", values="corr")
    # 调整列顺序,匹配目标格式
    .select("group", "name", "a", "b", "c")
)

print(result)

方法二:直接生成目标格式(更高效)

无需生成扁平结果,直接在分组聚合时构造结构化数据,一步得到目标格式:

cols = ["a", "b", "c"]

result = (
    df
    .group_by("group")
    # 对每个分组,构造嵌套结构的相关矩阵
    .agg(
        pl.struct(
            {
                col1: pl.struct(
                    {col2: pl.corr(col1, col2) for col2 in cols}
                )
                for col1 in cols
            }
        ).alias("corr_matrix")
    )
    # 展开嵌套结构,得到行名和对应列的相关系数
    .melt(id_vars="group", value_name="corr_data")
    .rename({"variable": "name"})
    # 将嵌套字段展开为单独列
    .unnest("corr_data")
)

print(result)

这个方法避免了冗余的扁平列生成,逻辑更直接,性能更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:44:55