我想知道如何用随机值填充极坐标数据框的列。 我的想法是,我有一个具有给定列数的数据框,并且我想向该数据框添加一列,该数据框填充有不同的随机值(例如从 random.random() 函数获得)。
这是我现在尝试的:
df = df.with_columns(
pl.when((pl.col('Q') > 0)).then(random.random()).otherwise(pl.lit(1)).alias('Prob')
)
通过这种方法,我获得的结果是一列填充了一个随机值即所有行都具有相同的值。
有没有办法用不同的随机值填充列?
提前致谢。
您需要一个与数据框高度相同的随机数“列”?
np.random.rand
对此很有用:
df = pl.DataFrame({"foo": [1, 2, 3]})
df.with_columns(pl.lit(np.random.rand(df.height)).alias("prob"))
shape: (3, 2)
┌─────┬──────────┐
│ foo ┆ prob │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞═════╪══════════╡
│ 1 ┆ 0.657389 │
│ 2 ┆ 0.616265 │
│ 3 ┆ 0.142611 │
└─────┴──────────┘
df.with_columns(
pl.when(pl.col("foo") > 2).then(pl.lit(np.random.rand(df.height)))
.alias("prob")
)
shape: (3, 2)
┌─────┬──────────┐
│ foo ┆ prob │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞═════╪══════════╡
│ 1 ┆ null │
│ 2 ┆ null │
│ 3 ┆ 0.686551 │
└─────┴──────────┘
也可以用表达式做类似的事情吗?
.int_range()
和 .sample()
df.with_columns(
(pl.int_range(1000).sample(pl.len(), with_replacement=True) / 1000)
.alias("prob")
)
shape: (3, 2)
┌─────┬───────┐
│ foo ┆ prob │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞═════╪═══════╡
│ 1 ┆ 0.288 │
│ 2 ┆ 0.962 │
│ 3 ┆ 0.734 │
└─────┴───────┘
首先获取数据框的行数:
row_n = df.select(pl.count()).collect().items()
然后使用 random 创建一个该大小的随机列表:
to_add = random.sample(range(0, 10), row_n)
最后将其添加到您的数据框中:
df.with_column(pl.Series(name="new_col", values=to_add))
创建示例极坐标数据框
df = pl.DataFrame({
'Q': [1, -1, -3, 4],
})
一次线性矢量化计算
df = df.with_columns(
pl.when(pl.col('Q') > 0)
.then(pl.lit(np.random.uniform(0, 1, len(df))))
.otherwise(1)
.alias('Prob')
)
结果
Q Prob
1 0.922802
-1 1.0
-3 1.0
4 0.182397
首先,如果您仍在使用
with_column
而不是 with_columns
,那么您使用的 Polars 版本相对较旧,因此我建议升级,因为有新功能和性能增强。还有一些重大变化,比如不再有 with_column
,因为它是多余的,因为它从一开始就只是 with_columns
的限制版本。
抛开这一点,对于你的问题,它不起作用的原因是当你跑步时
df.with_columns(pl.when((pl.col('Q') > 0)).then(random.random()).otherwise(pl.lit(1)).alias('Prob'))
python 仅调用
random.random()
一次,并且由于它只返回一个值,因此 Polars 将其广播(即复制)到所有行。你需要做的是告诉 python 在你真正“需要”的时候运行它。我将 need 放在引号中,因为如果您尝试给它的值少于 df 的整个高度,即使您只需要与 Q>0 一样多的随机值,极坐标也会抱怨。
最简单的方法就是使用列表理解插入
df
的高度
df.with_columns(
pl.when((pl.col('Q') > 0))
.then(pl.lit([random.random() for _ in range(df.height)]))
.otherwise(pl.lit(1))
.alias('Prob'))
对
random.random()
使用列表理解并不像让 numpy 创建随机数数组那么高效,因为它使用优化的 C 代码来完成此操作,而列表理解只是一个 Python 循环。我打算回答为什么它不起作用的总体问题,而不是规定最快的随机数生成方法。
你可以这样做:
df.with_columns(
pl.Series(
[random.random() if q > 0 else 1 for q in df["Q"]]
).alias("Prob")
)