这是一个基于实际工作负载的简单基准。
import gc
import time
import numpy as np
import polars as pl
df = ( # I have a dataframe like this from reading a csv.
pl.Series(
name="x",
values=np.random.choice(
["ASPARAGUS", "BROCCOLI", ""], size=30_000_000
),
)
.to_frame()
.with_columns(
pl.when(pl.col("x") == "").then(None).otherwise(pl.col("x"))
)
)
start = time.time()
df.lazy().with_columns(
pl.col("x").cast(pl.Categorical).fill_null("MISSING")
).collect()
end = time.time()
print(f"Cast then fill_null took {end-start:.2f} seconds.")
投射然后 fill_null 花了 0.93 秒。
gc.collect()
start = time.time()
df.lazy().with_columns(
pl.col("x").fill_null("MISSING").cast(pl.Categorical)
).collect()
end = time.time()
print(f"Fill_null then cast took {end-start:.2f} seconds.")
Fill_null 然后投射花了 1.36 秒。
(1) 我是否正确地认为转换为分类然后填充 null 总是会更快?
(2) 我认为无论顺序如何,结果总是相同,这样的想法正确吗?
(3)如果答案是“是”和“是”,是否有可能有一天,极地会自动进行这种重新排列?或者实际上不可能在通用查询优化器中尝试所有这些排列?
谢谢。
1:是的
2:有一点。逻辑范畴表示总是相同的。物理变化按字符串值的出现顺序进行。在演员之前做
fill_null
,意味着"MISSING"
会更早被发现。但这应该被视为一个实现细节。
3:是的,这是我们可以自动优化的。就在今天,我们合并了类似的东西:https://github.com/pola-rs/polars/pull/4883