将字符串列表中的操作应用到极坐标中的一(或多)列

问题描述 投票:0回答:4

我需要对单个列应用多个简单运算(求和/平均值/最大值/最小值/中值等)。有没有办法写得简洁而不重复自己?

现在我需要手动编写所有这些,

df.select(pl.col("a").max(), pl.col("b").mean(), pl.col("b").min())

而在 pandas 中,我可以将操作列表([“max”,“min”,“mean”])传递给 agg

查看了 Polars 文档和互联网,找不到任何东西

python-polars
4个回答
4
投票

您可以使用

getattr
将您想要的表达式字符串“转换”为可操作的字符串。 这样你就可以做到这一点...

df=pl.DataFrame({'a':[1,2,3,4], 'b':[3,4,5,6]})

(
    df
        .select(getattr(pl.col(col), fun)().name.suffix(f"_{fun}") 
                    for col in ['a','b'] 
                    for fun in ["max", "min", "mean"])
)

shape: (1, 6)
┌───────┬───────┬────────┬───────┬───────┬────────┐
│ a_max ┆ a_min ┆ a_mean ┆ b_max ┆ b_min ┆ b_mean │
│ ---   ┆ ---   ┆ ---    ┆ ---   ┆ ---   ┆ ---    │
│ i64   ┆ i64   ┆ f64    ┆ i64   ┆ i64   ┆ f64    │
╞═══════╪═══════╪════════╪═══════╪═══════╪════════╡
│ 4     ┆ 1     ┆ 2.5    ┆ 6     ┆ 3     ┆ 4.5    │
└───────┴───────┴────────┴───────┴───────┴────────┘

如果您只想要所有列,可以取出

for col in ['a','b']
并将
pl.col(col)
更改为
pl.all()

您甚至可以使用双迭代生成器来复制此语法

{'a' : ['sum', 'min'], 'b' : ['min', 'max']}

(
    df
    .select(getattr(pl.col(col), fun)().name.suffix(f"_{fun}") 
            for col,funL in {'a' : ['sum', 'min'], 'b' : ['min', 'max']}.items() 
            for fun in funL)
)

最后,您可以将所有内容包装到一个函数中,然后将其修补到

pl.DataFrame.agg
,这样您就拥有了您正在寻找的直接功能。

def agg(df, func: str | list | dict) -> pl.DataFrame:
    """Function to replicate pandas agg function, will take either a single string, a list of strings, or a dict mapping columns to functions"""
    if isinstance(func, str):
        func=[func]
    if isinstance(func, list):
        return (
            df
                .select(getattr(pl.all(), fun)().name.suffix(f"_{fun}") for fun in func)
        )
    elif isinstance(func, dict):
        return (
            df
            .select(getattr(pl.col(col), fun)().name.suffix(f"_{fun}")
                    for col,funL in func.items()
                    for fun in funL)
        )
pl.DataFrame.agg=agg

现在你可以做

df.agg(['min','max'])
shape: (1, 6)
┌───────┬───────┬───────┬───────┬────────┬────────┐
│ a_min ┆ b_min ┆ a_max ┆ b_max ┆ a_mean ┆ b_mean │
│ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---    ┆ ---    │
│ i64   ┆ i64   ┆ i64   ┆ i64   ┆ f64    ┆ f64    │
╞═══════╪═══════╪═══════╪═══════╪════════╪════════╡
│ 1     ┆ 3     ┆ 4     ┆ 6     ┆ 2.5    ┆ 4.5    │
└───────┴───────┴───────┴───────┴────────┴────────┘

df.agg({'a' : ['sum', 'min'], 'b' : ['min', 'max']})
shape: (1, 4)
┌───────┬───────┬───────┬───────┐
│ a_sum ┆ a_min ┆ b_min ┆ b_max │
│ ---   ┆ ---   ┆ ---   ┆ ---   │
│ i64   ┆ i64   ┆ i64   ┆ i64   │
╞═══════╪═══════╪═══════╪═══════╡
│ 10    ┆ 1     ┆ 3     ┆ 6     │
└───────┴───────┴───────┴───────┘

3
投票

.describe()
可能有用:

>>> df.describe()
shape: (9, 3)
┌────────────┬──────────┬──────────┐
│ describe   ┆ a        ┆ b        │
│ ---        ┆ ---      ┆ ---      │
│ str        ┆ f64      ┆ f64      │
╞════════════╪══════════╪══════════╡
│ count      ┆ 4.0      ┆ 4.0      │
│ null_count ┆ 0.0      ┆ 0.0      │
│ mean       ┆ 2.5      ┆ 4.5      │
│ std        ┆ 1.290994 ┆ 1.290994 │
│ min        ┆ 1.0      ┆ 3.0      │
│ max        ┆ 4.0      ┆ 6.0      │
│ median     ┆ 2.5      ┆ 4.5      │
│ 25%        ┆ 2.0      ┆ 4.0      │
│ 75%        ┆ 4.0      ┆ 6.0      │
└────────────┴──────────┴──────────┘

您还可以定义自己的辅助函数

pl.Expr.stats = lambda self, *exprs: (
   getattr(self, expr)().name.suffix(f"_{expr}") for expr in exprs
)
df.select( pl.col("a").stats("max", "min", "mean", "sum") )
shape: (1, 4)
┌───────┬───────┬────────┬───────┐
│ a_max ┆ a_min ┆ a_mean ┆ a_sum │
│ ---   ┆ ---   ┆ ---    ┆ ---   │
│ i64   ┆ i64   ┆ f64    ┆ i64   │
╞═══════╪═══════╪════════╪═══════╡
│ 4     ┆ 1     ┆ 2.5    ┆ 10    │
└───────┴───────┴────────┴───────┘
df.select( pl.all().stats("max", "min", "mean", "sum") )
shape: (1, 8)
┌───────┬───────┬───────┬───────┬────────┬────────┬───────┬───────┐
│ a_max ┆ b_max ┆ a_min ┆ b_min ┆ a_mean ┆ b_mean ┆ a_sum ┆ b_sum │
│ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---    ┆ ---    ┆ ---   ┆ ---   │
│ i64   ┆ i64   ┆ i64   ┆ i64   ┆ f64    ┆ f64    ┆ i64   ┆ i64   │
╞═══════╪═══════╪═══════╪═══════╪════════╪════════╪═══════╪═══════╡
│ 4     ┆ 6     ┆ 1     ┆ 3     ┆ 2.5    ┆ 4.5    ┆ 10    ┆ 18    │
└───────┴───────┴───────┴───────┴────────┴────────┴───────┴───────┘

2
投票

您可以进行一些

meta
编程:

df = pl.DataFrame({
    "a": [1, 2],
    "b": [3, 2],
})

df.select(
    eval(f"pl.all().{agg}().name.suffix('_{agg}')") for agg in ["min", "max", "var"]
)

2
投票

最短的本地方式可能是这样的:

df.select(pl.all().min().name.suffix("_min"), pl.all().max().name.suffix("_max"))
© www.soinside.com 2019 - 2024. All rights reserved.