假设我有一个嵌套框架,其中有一个名为mean
的列,我想将其用作随机数生成器的输入。来自R,这在管道中相对容易做到:
library(dplyr)
tibble(alpha = rnorm(1000),
beta = rnorm(1000)) %>%
mutate(mean = alpha + beta) %>%
bind_cols(random_output = rnorm(n = nrow(.), mean = .$mean, sd = 1))
#> # A tibble: 1,000 × 4
#> alpha beta mean random_output
#> <dbl> <dbl> <dbl> <dbl>
#> 1 0.231 -0.243 -0.0125 0.551
#> 2 0.213 0.647 0.861 0.668
#> 3 0.824 -0.353 0.471 0.852
#> 4 0.665 -0.916 -0.252 -1.81
#> 5 -0.850 0.384 -0.465 -3.90
#> 6 0.721 0.679 1.40 2.54
#> 7 1.46 0.857 2.32 2.14
#> 8 -0.242 -0.431 -0.673 -0.820
#> 9 0.234 0.188 0.422 -0.662
#> 10 -0.494 -2.15 -2.65 -3.01
#> # ℹ 990 more rows
字符串
创建于2023-11-12使用reprex v2.0.2
在python中,我可以创建一个中间框架并将其用作np.random.normal()
的输入,然后将其绑定到框架,但这感觉很笨拙。有没有一种方法可以将random_output
col作为管道/链的一部分添加?
import polars as pl
import numpy as np
# create a df
df = (
pl.DataFrame(
{
"alpha": np.random.standard_normal(1000),
"beta": np.random.standard_normal(1000)
}
)
.with_columns(
(pl.col("alpha") + pl.col("beta")).alias("mean")
)
)
# create an intermediate object
sim_vals = np.random.normal(df.get_column("mean"))
# bind the simulated values to the original df
(
df.with_columns(random_output = pl.lit(sim_vals))
)
#> shape: (1_000, 4)
┌───────────┬───────────┬───────────┬───────────────┐
│ alpha ┆ beta ┆ mean ┆ random_output │
│ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 ┆ f64 │
╞═══════════╪═══════════╪═══════════╪═══════════════╡
│ -1.380249 ┆ 1.531959 ┆ 0.15171 ┆ 0.938207 │
│ -0.332023 ┆ -0.108255 ┆ -0.440277 ┆ 0.081628 │
│ -0.718319 ┆ -0.612187 ┆ -1.330506 ┆ -1.286229 │
│ 0.22067 ┆ -0.497258 ┆ -0.276588 ┆ 0.908147 │
│ … ┆ … ┆ … ┆ … │
│ 0.299117 ┆ -0.371846 ┆ -0.072729 ┆ 0.592632 │
│ 0.789633 ┆ 0.95712 ┆ 1.746753 ┆ 2.954801 │
│ -0.264415 ┆ -0.761634 ┆ -1.026049 ┆ -1.369753 │
│ 1.893911 ┆ 1.554736 ┆ 3.448647 ┆ 5.192537 │
└───────────┴───────────┴───────────┴───────────────┘
型
1条答案
按热度按时间sh7euo9m1#
有四种方法(我能想到的),其中两种在评论中提到,一种我使用,最后一种我知道它存在,但没有亲自使用它。
第一个(get_column(col)或列'col'])引用
使用
df.get_column
作为np.random.normal
的参数,如果使用pipe
,则可以在链中执行此操作,例如字符串
秒(map_batches)
使用
map_batches
作为表达式型
第三次(numba)
这种方法比前两种方法更快,如果你要做很多随机化,但需要更多的设置(因此需要注意很多随机化)
numba允许您创建ufuncs,这些ufuncs是可以直接在表达式中使用的编译函数。
您可以创建此函数,它仅使用默认标准差
型
那么你可以做
型
更多阅读:
使成向量
另一个Numba例子
limitation
第四个( rust 扩展)
不幸的是,对于这个答案(我想我自己一般),我没有涉足rust编程,但有一个扩展接口,你可以在rust中创建函数并将其部署为表达式。
性能
使用1 M行df我得到.
第一种方法:71.1 ms ± 8.06 ms/循环(7次运行的平均值±标准差,每次1个循环)
第二种方法:70.7 ms ± 7.88 ms/循环(7次运行的平均值±标准差,每次10个循环)
第三种方法:45.7 ms ± 2.86 ms/循环(7次运行的平均值±标准差,每次10个循环)
需要注意的一点是,它并不快,除非你想为每一行使用不同的平均值,例如...
df.with_columns(z=rando(pl.repeat(5,pl.count())))
:43.8 ms ± 2.12 ms/循环(7次运行的平均值±标准差,每次10个循环)df.with_columns(z=pl.Series(np.random.normal(5,1,df.shape[0])))
:39.6 ms ± 3.64 ms/循环(7次运行的平均值±标准差,每次10个循环)