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

Polars按列名前缀分组指定列的实现问题(替代Pandas写法)

Polars按列名前缀分组的正确实现方式

现有如下DataFrame,除首列position外,其余列均以.0和.1后缀成对出现。需要通过提取列名中.前的前缀,对这些列按列分组并进行聚合操作。Pandas中已有可行实现,但Polars中尝试多种写法均报错,现求正确实现方式。

示例DataFrame

position    1164_1164.0 1164_1164.1 yes_001.0   yes_001.1   10316.0 10316.1 10349.0 10349.1 10418.0 10418.1
4414    0   1   0   0   1   0   0   0   1   1
5295    0   1   0   0   1   0   0   0   1   1
5738    0   1   0   0   1   0   0   0   1   1
5785    0   1   0   0   1   0   0   0   1   1
6392    0   1   0   0   1   0   0   0   1   1
7727    1   1   0   0   1   0   0   0   1   1
8876    1   1   0   0   1   0   0   0   1   1
9018    1   1   0   0   1   0   0   0   1   1
9208    1   1   0   0   1   0   1   0   1   1
9627    1   1   0   0   1   0   1   0   1   0

Pandas实现代码

g = df.iloc[:,1:].groupby(df.columns[1:].str.extract(r'(\w+)\.', expand=False), axis=1)
# 后续可通过g.sum()等操作完成聚合

Polars尝试的错误写法及报错

  • 错误写法1:直接对列名列表调用str.extract
    g = df[:,1:].groupby(df.columns[1:])
    # 尝试给df.columns[1:]加str.extract时报错:AttributeError: 'list' object has no attribute 'str'
    
  • 错误写法2:用pl.col("*").str.extract分组
    g = df[:,1:].groupby(pl.col("*").str.extract(r'(\w+)\.'))
    # 执行sum聚合时报错:DuplicateError: column with name '1164_1164.0' has more than one occurrences
    

正确的Polars实现方式

方法一:批量列选择+聚合

直接通过列名前缀筛选列,批量完成聚合:

import polars as pl

# 获取除首列外的所有列
target_cols = df.columns[1:]
# 提取所有唯一前缀
prefixes = {col.split('.')[0] for col in target_cols}

# 按前缀分组求和,保留position列
result = df.select(
    pl.col("position"),
    *[
        pl.col([col for col in target_cols if col.startswith(prefix)]).sum().alias(prefix)
        for prefix in prefixes
    ]
)

方法二: melt+groupby+pivot(灵活适配复杂聚合)

将宽表转长表后分组,再转回宽表,适合多类型聚合场景:

import polars as pl

# 转长格式,保留position作为标识列
melted_df = df.melt(id_vars="position", var_name="col_name", value_name="value")

# 提取列名前缀
melted_df = melted_df.with_columns(
    pl.col("col_name").str.extract(r'^(.+?)\.', 1).alias("prefix")
)

# 按position和前缀分组求和,再转回宽格式
result = melted_df.groupby(["position", "prefix"]).agg(
    pl.col("value").sum()
).pivot(
    index="position", columns="prefix", values="value"
)

方法三:列名映射分组

通过字典映射列名到前缀,再批量聚合:

import polars as pl

# 生成列名到前缀的映射字典
col_prefix_map = {col: col.split('.')[0] for col in df.columns[1:]}
# 获取唯一前缀
unique_prefixes = set(col_prefix_map.values())

# 按前缀聚合
result = df.select(
    pl.col("position"),
    *[
        pl.col([k for k, v in col_prefix_map.items() if v == prefix]).sum().alias(prefix)
        for prefix in unique_prefixes
    ]
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:30:05