
本教程旨在解决在polars lazyframes中进行多列元素级乘法操作时,如何高效地排除特定索引列的问题。通过利用polars的`struct`表达式和`join`操作,我们能够将非索引列封装成结构体,进行对齐和乘法运算,最后再将结果展开,从而实现类似pandas中dataframe直接相乘的简洁效果,同时保持polars的惰性计算优势。
在数据处理领域,对两个数据框(DataFrame)进行列与列之间的元素级乘法是一种常见的操作。例如,在Pandas中,如果两个DataFrame具有相同的索引和列结构,可以直接使用乘法运算符 df1 * df2 来实现这一目标,同时保持索引不变。然而,在Polars的LazyFrame环境中,由于其惰性计算的特性以及对“索引”概念的不同处理方式(Polars通常不强制要求索引,而是依赖于显式连接键),直接的 df1 * df2 语法并不适用。
当我们需要对两个LazyFrame中除特定“索引”列(如时间戳列)之外的所有数值列进行乘法运算时,传统的 concat 后 group_by 加聚合函数(如 sum)的方法,对于乘法聚合(product)并不总是直观或有效的,特别是当我们需要的是列与列之间的元素级乘积而非组内乘积时。本教程将介绍一种利用Polars的结构体(struct)和连接(join)功能来优雅地解决这一问题的方法。
Polars的struct表达式允许我们将多个列封装成一个复合的结构体列。这个特性在处理复杂数据结构或需要对一组相关列进行统一操作时非常有用。结合join操作,我们可以将两个LazyFrame中需要进行运算的非索引列作为结构体进行对齐,然后直接对这些结构体执行元素级运算,最后再将结果结构体展开回独立的列。
首先,我们创建两个结构相似的Polars LazyFrame,它们都包含一个time列作为“索引”以及foo、bar、baz等数值列。
import polars as pl
import pandas as pd
import numpy as np
# 设置随机数种子以确保结果可复现
np.random.seed(42)
n = 5 # 示例数据行数
df1_lazy = pl.DataFrame(data={
'time': pd.date_range('2023-01-01', periods=n, freq='1 min'),
'foo': np.random.uniform(0, 127, size=n).astype(np.float64),
'bar': np.random.uniform(1e3, 32767, size=n).astype(np.float64),
'baz': np.random.uniform(1e6, 2147483, size=n).astype(np.float64)
}).lazy()
df2_lazy = pl.DataFrame(data={
'time': pd.date_range('2023-01-01', periods=n, freq='1 min'),
'foo': np.random.uniform(0, 127, size=n).astype(np.float64),
'bar': np.random.uniform(1e3, 32767, size=n).astype(np.float64),
'baz': np.random.uniform(1e6, 2147483, size=n).astype(np.float64)
}).lazy()
print("df1_lazy 示例:")
print(df1_lazy.collect())
print("\ndf2_lazy 示例:")
print(df2_lazy.collect())对于每个LazyFrame,我们首先选择time列,然后使用pl.struct(pl.exclude("time"))表达式将所有非time列封装到一个名为cols的结构体列中。pl.exclude("time")是一个非常实用的表达式,它允许我们动态地选择除指定列之外的所有列,这使得代码更具通用性,无需硬编码所有列名。
df1_struct = df1_lazy.select("time", cols=pl.struct(pl.exclude("time")))
df2_struct = df2_lazy.select("time", cols=pl.struct(pl.exclude("time")))
print("\ndf1_struct 示例:")
print(df1_struct.collect())可以看到,foo, bar, baz 列被合并到了一个名为 cols 的结构体中。
接下来,我们使用left-join操作将这两个带有结构体列的LazyFrame连接起来。连接键是time列,这确保了两个LazyFrame中对应时间戳的数据行能够正确对齐。
joined_df = df1_struct.join(
df2_struct,
on="time",
how="left"
)
print("\n连接后的 LazyFrame 示例:")
print(joined_df.collect())连接后,我们会得到一个包含time、cols(来自df1_struct)和cols_right(来自df2_struct)的LazyFrame。cols_right是Polars在连接时自动为右侧DataFrame的同名列添加的后缀。
Polars支持对结构体列进行元素级运算,只要结构体内部的字段是兼容的。因此,我们可以直接将cols列与cols_right列相乘:pl.col("cols") * pl.col("cols_right")。这将对两个结构体中同名字段进行逐个乘法运算。
最后,使用unnest("cols")方法将运算结果的结构体列展开,恢复成原始的独立列。
final_result_lazy = joined_df.select(
"time",
pl.col("cols") * pl.col("cols_right")
).unnest("cols")
print("\n最终乘法结果:")
print(final_result_lazy.collect())将上述步骤整合到一起,形成一个完整的解决方案:
import polars as pl
import pandas as pd
import numpy as np
# 设置随机数种子以确保结果可复现
np.random.seed(42)
n = 5 # 示例数据行数
# 创建两个Polars LazyFrame
df1_lazy = pl.DataFrame(data={
'time': pd.date_range('2023-01-01', periods=n, freq='1 min'),
'foo': np.random.uniform(0, 127, size=n).astype(np.float64),
'bar': np.random.uniform(1e3, 32767, size=n).astype(np.float64),
'baz': np.random.uniform(1e6, 2147483, size=n).astype(np.float64)
}).lazy()
df2_lazy = pl.DataFrame(data={
'time': pd.date_range('2023-01-01', periods=n, freq='1 min'),
'foo': np.random.uniform(0, 127, size=n).astype(np.float64),
'bar': np.random.uniform(1e3, 32767, size=n).astype(np.float64),
'baz': np.random.uniform(1e6, 2147483, size=n).astype(np.float64)
}).lazy()
# 执行多列乘法操作,排除 'time' 列
result_df = (
df1_lazy.select("time", cols=pl.struct(pl.exclude("time"))) # df1的非time列封装为struct
.join(
df2_lazy.select("time", cols=pl.struct(pl.exclude("time"))), # df2的非time列封装为struct
on="time",
how="left"
)
.select("time", pl.col("cols") * pl.col("cols_right")) # 结构体相乘
.unnest("cols") # 展开结果结构体
.collect() # 触发计算
)
print("\n最终计算结果 DataFrame:")
print(result_df)尽管Polars LazyFrame在多列运算上与Pandas的直接语法有所不同,但通过巧妙地利用pl.struct表达式将非索引列封装成结构体,并通过join操作进行对齐,我们能够实现高效且语义清晰的列与列之间元素级乘法。这种方法不仅充分发挥了Polars惰性计算的性能优势,也为处理更复杂的跨DataFrame列操作提供了通用的模式。
以上就是Polars LazyFrame 多列乘法操作:排除索引列的高效策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号