Aks*_*hay 3 dataframe python-polars
我对 Polar 还比较陌生。我对其运作有一些疑问。我可以在 Polars 中执行这样的操作,
df = df.with_columns(((pl.col("netsales")/pl.col("sold_quantity")).alias("net_div"))
Run Code Online (Sandbox Code Playgroud)
同样可以使用以下方法实现,
df = df.with_columns((df["netsales"]/df["sold_quantity"]).alias("net_div"))
Run Code Online (Sandbox Code Playgroud)
就性能而言,它们之间有什么区别吗?
还,
df = df.with_columns((df["netsales"]/df["sold_quantity"]).alias("net_mul"),
(df["netsales"]+df["sold_quantity"]).alias("net_add")
)
Run Code Online (Sandbox Code Playgroud)
上述操作可以像这样单独完成,
df = df.with_columns((df["netsales"]/df["sold_quantity"]).alias("net_mul"))
df = df.with_columns((df["netsales"]+df["sold_quantity"]).alias("net_add"))
Run Code Online (Sandbox Code Playgroud)
上述两种方式执行相同的操作在性能上有什么区别吗?我在网上找不到与此相关的任何答案或文档。如果您能分享一些这方面的知识,我将感谢您的支持。
df = df.with_columns((df["netsales"]/df["sold_quantity"]).alias("net_div"))
Run Code Online (Sandbox Code Playgroud)
退后一步,当你打电话时会发生什么df["netsales"]
?
它将该列提取为与该列同名的系列。当您将一个系列除以另一个系列时,它会产生另一个具有每个元素商的系列,正如您所期望的那样。
with_columns
当您喂食系列时会发生什么?它要么添加一列,要么用该数据替换现有列(假设它们具有相同的高度)。
由于Python的操作顺序,Python将在Polars知道你在做什么之前解决系列除法,所以没有办法插入一个警告,告诉你不应该这样做。
import polars as pl
import numpy as np
df=pl.DataFrame({
'a':np.random.normal(5,2,int(10e7)),
'b':np.random.normal(5,2,int(10e7)),
'c':np.random.normal(5,2,int(10e7)),
'd':np.random.normal(5,2,int(10e7)),
'e':np.random.normal(5,2,int(10e7))
})
Run Code Online (Sandbox Code Playgroud)
df.with_columns(df[x]**2.3 for x in df.columns)
# takes 7.9s and only uses one core
Run Code Online (Sandbox Code Playgroud)
df.with_columns(pl.col(x)**2.3 for x in df.columns)
# takes 2.2s and uses 5 cores, corresponding to 5 columns
Run Code Online (Sandbox Code Playgroud)
默认情况下,Polars 会自动并行运行所有表达式。当您使用方括号表示法时,您就不允许这种情况发生。你不允许这种情况发生的原因是 python 将在将生成器交给它之前解析生成器中的所有元素,with_columns
并且由于 python 本质上是串行的,这就是你得到的。
在表达式的情况下,你可以这样做
df.with_columns(pl.all()**2.3)
Run Code Online (Sandbox Code Playgroud)
还有一整套列选择器可以微调选择列。
with_columns
此外,使用表达式可以让您将多个、等链接在一起filter
,并且表达式根据上下文执行
例如你不能这样做
(
df
.filter(pl.col('netsales')<1000)
.with_columns(
df["netsales"]/df["sold_quantity"]
)
)
Run Code Online (Sandbox Code Playgroud)
因为df["netsales"]
不知道过滤器,所以尺寸会错误。
通过表达式,你可以做到
(
df
.filter(pl.col('netsales')<1000)
.with_columns(pl.col("netsales")/pl.col("sold_quantity"))
)
Run Code Online (Sandbox Code Playgroud)
对于 LazyFrames,数据尚未制成表格,因此您不能使用方括号表示法。