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

如何在Pandas函数式管道中实现类似R中across的多列操作?

Pandas中实现类似R dplyr::across的函数式列处理方案

问题概述

能否在Pandas中遵循函数式管道原则(无副作用、结果仅依赖输入参数、保留所有原有列)的前提下,对指定列批量应用函数,替代多次调用assign的繁琐写法,找到R语言dplyr::across的等效实现?

答案是肯定的,以下是几种简洁且符合要求的实现方式:


原冗余实现(多次调用assign)

虽然可行,但写法重复繁琐:

import pandas as pd
df = (
    pd.DataFrame({
    "column_a":[0,3,4,2,1],
    "column_b":[1,2,4,5,18],
    "column_c":[2,4,25,25,26],
    "column_d":[2,4,-1,5,2],
    "column_e":[-1,-7,-8,-9,3]
    })
    .assign(column_a=lambda df:df["column_a"]+20)
    .assign(column_c=lambda df:df["column_c"]+20)
    .assign(column_e=lambda df:df["column_e"]/3)
    .assign(column_b=lambda df:df["column_b"]/3)
)
print(df)

对应R语言across的简洁写法:

library(dplyr)
df <-
tibble(
  column_a = c(0,3,4,2,1),
  column_b = c(1,2,4,5,18),
  column_c = c(2,4,25,25,26),
  column_d = c(2,4,-1,5,2),
  column_e = c(-1,-7,-8,-9,3)
) %>%
  mutate(across(c(column_a,column_c),~.x + 20),
         across(c(column_e,column_b),~.x / 3))

方法1:assign配合字典批量处理

通过向assign传递字典参数,一次完成多组列的不同函数处理,完全符合函数式管道要求:

import pandas as pd
df = (
    pd.DataFrame({
        "column_a":[0,3,4,2,1],
        "column_b":[1,2,4,5,18],
        "column_c":[2,4,25,25,26],
        "column_d":[2,4,-1,5,2],
        "column_e":[-1,-7,-8,-9,3]
    })
    .assign(
        **{col: lambda df, col=col: df[col] + 20 for col in ["column_a", "column_c"]},
        **{col: lambda df, col=col: df[col] / 3 for col in ["column_b", "column_e"]}
    )
)
print(df)
  • 注:col=col用于在lambda闭包中捕获当前循环的列名,避免闭包延迟绑定导致的列名错误。

方法2:自定义across风格函数

封装一个贴近R语法的自定义函数,通过pipe在管道中调用,语义更清晰:

import pandas as pd

def across(df, cols, func):
    # 对指定列应用函数,返回新DataFrame,无副作用
    return df.assign(**{col: func(df[col]) for col in cols})

df = (
    pd.DataFrame({
        "column_a":[0,3,4,2,1],
        "column_b":[1,2,4,5,18],
        "column_c":[2,4,25,25,26],
        "column_d":[2,4,-1,5,2],
        "column_e":[-1,-7,-8,-9,3]
    })
    .pipe(across, cols=["column_a", "column_c"], func=lambda x: x + 20)
    .pipe(across, cols=["column_b", "column_e"], func=lambda x: x / 3)
)
print(df)

方法3:transform批量处理同函数列

如果多列需要应用相同函数,可以用transform生成处理后的列,再通过assign合并:

import pandas as pd

df = (
    pd.DataFrame({
        "column_a":[0,3,4,2,1],
        "column_b":[1,2,4,5,18],
        "column_c":[2,4,25,25,26],
        "column_d":[2,4,-1,5,2],
        "column_e":[-1,-7,-8,-9,3]
    })
    .assign(**df[["column_a", "column_c"]].transform(lambda x: x + 20))
    .assign(**df[["column_b", "column_e"]].transform(lambda x: x / 3))
)
print(df)

以上所有方法均满足:

  • 无副作用:所有操作返回新的DataFrame,不修改原始输入数据
  • 结果仅依赖参数:处理逻辑完全由输入的列名和函数决定
  • 保留所有列:未指定的列(如column_d)会被完整保留

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:45:34