我有这个数据框:

shape: (5, 3)
┌───────────────┬──────────────┬────────────────────────┐
│ exchange_rate ┆ sig_figs_len ┆ reverse_rate_from_euro │
│ ---           ┆ ---          ┆ ---                    │
│ f64           ┆ u32          ┆ f64                    │
╞═══════════════╪══════════════╪════════════════════════╡
│ 6.4881        ┆ 5            ┆ 0.154128               │
│ 6.5196        ┆ 5            ┆ 0.153384               │
│ 6.4527        ┆ 5            ┆ 0.154974               │
│ 6.41          ┆ 3            ┆ 0.156006               │
│ 6.425         ┆ 4            ┆ 0.155642               │
└───────────────┴──────────────┴────────────────────────┘

我想用sig_figs_len列相应单元格中的匹配值来舍入reverse_rate_from_euro中每个单元格中的值.

我提出了一个使用APPLY/MAP_ROWS函数的解决方案,但由于数据集非常大,并且使用Apply/PURE PYTHON不是一个优化的理想解决方案,所以我想找到一个更好的解决方案.

下面是这个片段:

df = df.with_columns(
    (df.map_rows(lambda df_: round(df_[-1], df_[-2])))
    .to_series()
    .alias("reverse_rate_to_euro_rounded_sig_figs")

有没有更好的解决方案,使用任何内置的Polars表达式API?

结果集应如下所示:

shape: (5, 4)
┌───────────────┬──────────────┬────────────────────────┬───────────────────────────────────┐
│ exchange_rate ┆ sig_figs_len ┆ reverse_rate_from_euro ┆ reverse_rate_to_euro_rounded_sig… │
│ ---           ┆ ---          ┆ ---                    ┆ ---                               │
│ f64           ┆ u32          ┆ f64                    ┆ f64                               │
╞═══════════════╪══════════════╪════════════════════════╪═══════════════════════════════════╡
│ 6.4881        ┆ 5            ┆ 0.154128               ┆ 0.15413                           │
│ 6.5196        ┆ 5            ┆ 0.153384               ┆ 0.15338                           │
│ 6.4527        ┆ 5            ┆ 0.154974               ┆ 0.15497                           │
│ 6.41          ┆ 3            ┆ 0.156006               ┆ 0.156                             │
│ 6.425         ┆ 4            ┆ 0.155642               ┆ 0.1556                            │
└───────────────┴──────────────┴────────────────────────┴───────────────────────────────────┘

任何输入都是高度赞赏! 感谢阅读!

推荐答案

您可能会这样做:

df.with_columns(
    (
        pl.col('reverse_rate_from_euro') * 
        pl.lit(10).pow(pl.col('sig_figs_len'))
    ).round() * 
    pl.lit(0.1).pow(pl.col('sig_figs_len'))
)

┌───────────────┬──────────────┬────────────────────────┐
│ exchange_rate ┆ sig_figs_len ┆ reverse_rate_from_euro │
│ ---           ┆ ---          ┆ ---                    │
│ f64           ┆ i64          ┆ f64                    │
╞═══════════════╪══════════════╪════════════════════════╡
│ 6.4881        ┆ 3            ┆ 0.154                  │
│ 6.5196        ┆ 4            ┆ 0.1534                 │
└───────────────┴──────────────┴────────────────────────┘

或者,如果你知道不同的sig_figs_len值的数量并不多,你可以枚举超过unique()个值,然后用coalesce()when()创建结果:

df.with_columns(
    pl.coalesce(
        pl.when(pl.col("sig_figs_len") == x)
        .then(pl.col("reverse_rate_from_euro").round(x))
        for x in df['sig_figs_len'].unique()
    ).alias('reverse_rate_to_euro_rounded_sig_figs')
)

┌───────────────┬──────────────┬────────────────────────┬───────────────────────────────────┐
│ exchange_rate ┆ sig_figs_len ┆ reverse_rate_from_euro ┆ reverse_rate_to_euro_rounded_sig… │
│ ---           ┆ ---          ┆ ---                    ┆ ---                               │
│ f64           ┆ i64          ┆ f64                    ┆ f64                               │
╞═══════════════╪══════════════╪════════════════════════╪═══════════════════════════════════╡
│ 6.4881        ┆ 3            ┆ 0.154128               ┆ 0.154                             │
│ 6.5196        ┆ 4            ┆ 0.153384               ┆ 0.1534                            │
└───────────────┴──────────────┴────────────────────────┴───────────────────────────────────┘

本质上,我们在这里所做的是创建一个Iterable[IntoExpr],你可以看到它是一个列的列表,其中每一列只包含四舍五入到某个sig_figs_len值的值:

df.with_columns(
    pl.when(pl.col("sig_figs_len") == x)
    .then(pl.col("reverse_rate_from_euro").round(x)).name.suffix(f"_{x}")
     for x in df['sig_figs_len'].unique()
))

┌───────────────┬──────────────┬─────────────────────┬─────────────────────┬─────────────────────┬─────────────────────┐
│ exchange_rate ┆ sig_figs_len ┆ reverse_rate_from_e ┆ reverse_rate_from_e ┆ reverse_rate_from_e ┆ reverse_rate_from_e │
│ ---           ┆ ---          ┆ uro                 ┆ uro_3               ┆ uro_4               ┆ uro_5               │
│ f64           ┆ i64          ┆ ---                 ┆ ---                 ┆ ---                 ┆ ---                 │
│               ┆              ┆ f64                 ┆ f64                 ┆ f64                 ┆ f64                 │
╞═══════════════╪══════════════╪═════════════════════╪═════════════════════╪═════════════════════╪═════════════════════╡
│ 6.4881        ┆ 5            ┆ 0.154128            ┆ null                ┆ null                ┆ 0.15413             │
│ 6.5196        ┆ 5            ┆ 0.153384            ┆ null                ┆ null                ┆ 0.15338             │
│ 6.4527        ┆ 5            ┆ 0.154974            ┆ null                ┆ null                ┆ 0.15497             │
│ 6.41          ┆ 3            ┆ 0.156006            ┆ 0.156               ┆ null                ┆ null                │
│ 6.425         ┆ 4            ┆ 0.155642            ┆ null                ┆ 0.1556              ┆ null                │
└───────────────┴──────────────┴─────────────────────┴─────────────────────┴─────────────────────┴─────────────────────┘

然后我们使用pl.coalesce()接受Expr的可迭代性来获得第一个非空列

Python相关问答推荐

Polars比较了两个预设-有没有方法在第一次不匹配时立即失败

try 在树叶 map 上应用覆盖磁贴

Telethon加入私有频道

如何在solve()之后获得症状上的等式的值

try 将一行连接到Tensorflow中的矩阵

基于索引值的Pandas DataFrame条件填充

DataFrames与NaN的条件乘法

pandas在第1列的id,第2列的标题,第3列的值,第3列的值?

计算天数

如何在达到end_time时自动将状态字段从1更改为0

numpy.unique如何消除重复列?

Cython无法识别Numpy类型

在极点中读取、扫描和接收有什么不同?

修改.pdb文件中的值并另存为新的

使用xlsxWriter在EXCEL中为数据帧的各行上色

使用pythonminidom过滤XML文件

为什么在生成时间序列时,元组索引会超出范围?

将标签与山脊线图对齐

组颠倒大Pandas 数据帧

是否将列表分割为2?