我知道 Polars 表达式是按列并行化的,用于读取、计算以及输入/更改 DataFrame 中的数据。 所以,速度非常快...
但是,我找不到将行和列的特定值更改为df[1,'a']=12
的
Polars Expression我该怎么办?
以下是我想要的方法。
import polars as pl
df = pl.DataFrame(
{
"a": [1,2,3,4,5,6,7,8],
"b": [8,9,0,1,2,3,4,5],
"c": [0,0,0,0,0,0,0,0],
"d": [0,0,0,0,0,0,0,0],
}
)
df = df.with_columns(pl.all().cast(pl.Float64))
df[7,'c']=12
df[7,'d']=15
# I want this to below way that Polars Expressions
# => df.select(?)(
pl.col('c').row(7) = 12
pl.col('d').row(7) = 15
)
print(df)
shape: (8, 4)
┌─────┬─────┬──────┬──────┐
│ a ┆ b ┆ c ┆ d │
│ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 ┆ f64 │
╞═════╪═════╪══════╪══════╡
│ 1.0 ┆ 8.0 ┆ 0.0 ┆ 0.0 │
│ 2.0 ┆ 9.0 ┆ 0.0 ┆ 0.0 │
│ 3.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 │
│ 4.0 ┆ 1.0 ┆ 0.0 ┆ 0.0 │
│ 5.0 ┆ 2.0 ┆ 0.0 ┆ 0.0 │
│ 6.0 ┆ 3.0 ┆ 0.0 ┆ 0.0 │
│ 7.0 ┆ 4.0 ┆ 0.0 ┆ 0.0 │
│ 8.0 ┆ 5.0 ┆ 12.0 ┆ 15.0 │
└─────┴─────┴──────┴──────┘
极性数据帧是不可变的,这意味着您无法像 pandas 那样更新单个单元格值。你必须立即更换整个东西。后端内存足够智能,不需要复制它,但语法就是这样。
jquirous 尚未涵盖的一种方法是:
df = (
df.with_row_count('i')
.select(
pl.exclude('c','d'),
structcol=pl.when(pl.col('i')==7)
.then(pl.struct(c=12, d=15))
.otherwise(pl.struct(c=pl.col('c'), d=pl.col('d'))))
.unnest('structcol')
.drop('i')
)
本质上,您使用
with_row_count
创建一个表示行索引的列,然后,由于您想要更改两列,因此您使用一个结构来保存这两个值,稍后您将 unnest
。为了使 unnest
正常工作,您必须排除 c
和 d
列,否则 unnest
将因名称冲突而出错。最后,删除 i
列,以便最终得到与开始时相同的形状。
另一件可行但反模式的事情是将 df 切片,然后再次将其连接在一起
row_to_change=7
df=pl.concat([
df[0:row_to_change],
df[row_to_change].with_columns(c=12.0,d=15.0),
df[row_to_change+1:]])
顺便说一句,我建议无论您做什么来推断第 7 行是您想要更改的行,都将其合并到更改中,而不是根据行索引进行更改。换句话说,在此之前您已经有一个步骤告诉您第 7 行是要更改的行,现在是更改第 7 行的步骤。您应该将此步骤与该步骤合并并同时执行这两个步骤。
df[...] =
执行 .set_at_idx()
- 那里的文档显示了如何使用 .when
pl.when(pl.col("row_nr") == 1).then(10).otherwise(pl.col("a")).alias("a")
设置多个值将涉及每个值的表达式:
pl.when(pl.col("row_nr") == 1).then(10).otherwise(pl.col("a")).alias("a"),
pl.when(pl.col("row_nr") == 2).then(20).otherwise(pl.col("b")).alias("b")
以下是我见过的一些替代方法:
.map
内使用
.then
df.with_row_count().with_columns(
pl.when(pl.col("row_nr") == 7)
.then(pl.col("c", "d").map(lambda col: dict(c=12, d=15).get(col.name)))
.otherwise(pl.col("c", "d"))
).drop("row_nr")
.when/.then
df.with_row_count().with_columns(
pl.when(pl.col("row_nr") == row_nr)
.then(pl.lit(value).alias(col))
.otherwise(pl.col(col))
for row_nr, col, value in [
(7, "c", 12),
(7, "d", 15)
]
).drop("row_nr")
.update
changes = [dict(row_nr=7, c=12, d=15)]
(df.with_row_count()
.with_columns(pl.col("row_nr").cast(pl.Int64))
.update(
pl.DataFrame(changes),
on="row_nr")
.drop("row_nr"))
.update
和 .map_dict
df.update(
df.with_row_count()
.select(pl.col("row_nr").map_dict({7: dict(c=12, d=15)}))
.unnest("row_nr")
)