首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python-polars:如何将列表中的每个元素与不同列中的值相乘?

Python-polars:如何将列表中的每个元素与不同列中的值相乘?
EN

Stack Overflow用户
提问于 2022-11-09 08:55:06
回答 2查看 86关注 0票数 0

我有一个包含一定数量组的dataframe,包含一个权重列和一个值列表,这些值可以是任意长度的,例如:

代码语言:javascript
复制
df = pl.DataFrame(
    {
        "Group": ["Group1", "Group2", "Group3"],
        "Weight": [100.0, 200.0, 300.0],
        "Vals": [[0.5, 0.5, 0.8],[0.5, 0.5, 0.8], [0.7, 0.9]]
    }
)
代码语言:javascript
复制
┌────────┬────────┬─────────────────┐
│ Group  ┆ Weight ┆ Vals            │
│ ---    ┆ ---    ┆ ---             │
│ str    ┆ f64    ┆ list[f64]       │
╞════════╪════════╪═════════════════╡
│ Group1 ┆ 100.0  ┆ [0.5, 0.5, 0.8] │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Group2 ┆ 200.0  ┆ [0.5, 0.5, 0.8] │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Group3 ┆ 300.0  ┆ [0.7, 0.9]      │
└────────┴────────┴─────────────────┘

我的目标是计算一个“加权”列,它是值列表中每一项的倍数,而权重列中的值是:

代码语言:javascript
复制
┌────────┬────────┬─────────────────┬─────────────────┐
│ Group  ┆ Weight ┆ Vals            ┆ Weighted        │
│ ---    ┆ ---    ┆ ---             ┆ ---             │
│ str    ┆ f64    ┆ list[f64]       ┆ list[i64]       │
╞════════╪════════╪═════════════════╪═════════════════╡
│ Group1 ┆ 100.0  ┆ [0.5, 0.5, 0.8] ┆ [50, 50, 80]    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Group2 ┆ 200.0  ┆ [0.5, 0.5, 0.8] ┆ [100, 100, 160] │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Group3 ┆ 300.0  ┆ [0.7, 0.9]      ┆ [210, 270]      │
└────────┴────────┴─────────────────┴─────────────────┘

我尝试过几种不同的方法:

代码语言:javascript
复制
df.with_columns([
        pl.col("Vals").arr.eval(pl.element() * 3).alias("Weight1"), #Multiplying with literal works
        pl.col("Vals").arr.eval(pl.element() * pl.col("Weight")).alias("Weight2"), #Does not work
        pl.col("Vals").arr.eval(pl.element() * pl.col("Unknown")).alias("Weight3"), #Unknown columns give same value
        pl.col("Vals").arr.eval(pl.col("Vals") * pl.col("Weight")).alias("Weight4"), #Same effect
        # pl.col('Vals') * 3 -> gives an error
]
)
代码语言:javascript
复制
┌────────┬────────┬────────────┬────────────┬──────────────┬──────────────┬────────────────────┐
│ Group  ┆ Weight ┆ Vals       ┆ Weight1    ┆ Weight2      ┆ Weight3      ┆ Weight4            │
│ ---    ┆ ---    ┆ ---        ┆ ---        ┆ ---          ┆ ---          ┆ ---                │
│ str    ┆ f64    ┆ list[f64]  ┆ list[f64]  ┆ list[f64]    ┆ list[f64]    ┆ list[f64]          │
╞════════╪════════╪════════════╪════════════╪══════════════╪══════════════╪════════════════════╡
│ Group1 ┆ 100.0  ┆ [0.5, 0.5, ┆ [1.5, 1.5, ┆ [0.25, 0.25, ┆ [0.25, 0.25, ┆ [0.25, 0.25, 0.64] │
│        ┆        ┆ 0.8]       ┆ 2.4]       ┆ 0.64]        ┆ 0.64]        ┆                    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Group2 ┆ 200.0  ┆ [0.5, 0.5, ┆ [1.5, 1.5, ┆ [0.25, 0.25, ┆ [0.25, 0.25, ┆ [0.25, 0.25, 0.64] │
│        ┆        ┆ 0.8]       ┆ 2.4]       ┆ 0.64]        ┆ 0.64]        ┆                    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Group3 ┆ 300.0  ┆ [0.7, 0.9] ┆ [2.1, 2.7] ┆ [0.49, 0.81] ┆ [0.49, 0.81] ┆ [0.49, 0.81]       │
└────────┴────────┴────────────┴────────────┴──────────────┴──────────────┴────────────────────┘

除非我没有正确理解它,否则您似乎无法从eval函数中访问列表之外的列。也许有一种方法可以在语句中使用列表理解,但这看起来并不是一个很好的解决方案。

这里推荐的方法是什么?任何帮助都将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-09 15:35:40

我认为这对你有用:

代码语言:javascript
复制
(df
    .explode('Vals')
    .with_columns(Weighted = pl.col('Weight')*pl.col('Vals'))
    .groupby('Group')
    .agg([
        pl.col('Weight').first(),                                                                                                             
        pl.col('Vals').list(),
        pl.col('Weighted').list()
        ])                                                                                                 
)
票数 1
EN

Stack Overflow用户

发布于 2022-11-09 13:02:11

所以你可以用两种方法解决这个问题。老实说,我不知道哪个更好,我还没有测试性能或RAM的使用情况。

算法1

我们可以将两列都放在一个结构中,然后在它们上应用一个自定义函数。(这里文档中对此进行了解释)

代码语言:javascript
复制
import polars as pl
import numpy as np

def weighted_list(ls, weight):
    return(list(np.array(ls) * weight))

(df.with_columns([pl.struct(["Weight", "Vals"])
                  .apply(lambda x: weighted_list(x["Vals"], x["Weight"]))])
)

算法2

因此,在这种情况下,您必须小心,您的列“组”、“权重”是唯一的。因此,如果您有两个条目,例如Group3和with 300。

代码语言:javascript
复制
(df.explode("Vals")
    .with_column((pl.col("Vals") * pl.col("Weight")).alias("Weighted"))
    .groupby(["Group", "Weight"])
    .agg([pl.list("Vals"), pl.list("Weighted")])
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74372173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档