跳到内容

模式

Polars 的 DataFrameLazyFrame 的模式规定了列的名称及其数据类型。您可以使用 DataFrameLazyFrame 上的 .collect_schema 方法查看模式。

LazyFrame

lf = pl.LazyFrame({"foo": ["a", "b", "c"], "bar": [0, 1, 2]})

print(lf.collect_schema())

Schema({'foo': String, 'bar': Int64})

模式在惰性API中扮演着重要角色。

惰性API中的类型检查

惰性API的一个优点是,Polars 会在处理任何数据之前检查模式。此检查发生在您执行惰性查询时。

我们通过以下简单示例了解其工作原理,我们在字符串列 foo 上调用了 .round 表达式。

with_columns

lf = pl.LazyFrame({"foo": ["a", "b", "c"]}).with_columns(pl.col("foo").round(2))

.round 表达式仅对数值数据类型的列有效。在字符串列上调用 .round 意味着当您使用 collect 评估查询时,该操作将引发 InvalidOperationError 错误。此模式检查发生在调用 collect 时,即在数据处理之前。

try:
    print(lf.collect())
except Exception as e:
    print(f"{type(e).__name__}: {e}")
InvalidOperationError: round can only be used on numeric types

如果我们在急切模式下执行此查询,则只有在数据完成所有早期步骤的处理后,才会发现错误。

当我们执行惰性查询时,Polars 会在实际处理管道中数据这一耗时步骤之前,检查任何潜在的 InvalidOperationError

惰性API必须知道模式

在惰性API中,Polars 查询优化器必须能够在查询计划的每一步推断模式。这意味着模式无法提前知晓的操作不能与惰性API一起使用。

模式无法提前知晓的经典操作示例是 .pivot(透视)操作。在 .pivot 中,新列名来自其中一列中的数据。由于这些列名无法提前知道,因此 .pivot 在惰性API中不可用。

处理惰性API中不可用的操作

如果您的管道包含一个在惰性API中不可用的操作,通常最好的做法是:

  • 在该点之前以惰性模式运行管道
  • 使用 .collect 执行管道,以具体化一个 DataFrame
  • DataFrame 上执行非惰性操作
  • 使用 .lazy 将输出转换回 LazyFrame,然后继续在惰性模式下操作

我们在这个示例中展示了如何处理非惰性操作,具体步骤如下:

  • 创建一个简单的 DataFrame
  • 使用 .lazy 将其转换为 LazyFrame
  • 使用 .with_columns 进行转换
  • 在透视操作之前使用 .collect 执行查询以获取一个 DataFrame
  • DataFrame 上执行 .pivot
  • 转换回惰性模式
  • 执行 .filter
  • 最后使用 .collect 执行查询以获取一个 DataFrame

collect · lazy · pivot · filter

lazy_eager_query = (
    pl.LazyFrame(
        {
            "id": ["a", "b", "c"],
            "month": ["jan", "feb", "mar"],
            "values": [0, 1, 2],
        }
    )
    .with_columns((2 * pl.col("values")).alias("double_values"))
    .collect()
    .pivot(index="id", on="month", values="double_values", aggregate_function="first")
    .lazy()
    .filter(pl.col("mar").is_null())
    .collect()
)
print(lazy_eager_query)

shape: (2, 4)
┌─────┬──────┬──────┬──────┐
│ id  ┆ jan  ┆ feb  ┆ mar  │
│ --- ┆ ---  ┆ ---  ┆ ---  │
│ str ┆ i64  ┆ i64  ┆ i64  │
╞═════╪══════╪══════╪══════╡
│ a   ┆ 0    ┆ null ┆ null │
│ b   ┆ null ┆ 2    ┆ null │
└─────┴──────┴──────┴──────┘