使用 Polars 计算布尔(或数字)列中连续的 True(或 1)值?

JGr*_*t06 5 python-polars

我希望计算列中的连续值,最好使用 Polars 表达式。

import polars
df = pl.DataFrame(
   {"values": [True,True,True,False,False,True,False,False,True,True]}
)
Run Code Online (Sandbox Code Playgroud)

通过上面的示例数据框,我想计算连续 True 值的数量。

下面是使用 R 的 Data.Table 包的示例输出。

library(data.table)
dt <- data.table(value = c(T,T,T,F,F,T,F,F,T,T))
dt[, value2 := fifelse((1:.N) == .N & value == 1, .N, NA_integer_), by = rleid(value)]
dt
Run Code Online (Sandbox Code Playgroud)
价值 值2
真的 不适用
真的 不适用
真的 3
错误的 不适用
错误的 不适用
真的 1
错误的 不适用
错误的 不适用
真的 不适用
真的 2

有什么想法可以使用 Polars 有效地完成此操作吗?

[用新方法编辑]

我用下面的代码让它工作,但希望有一种更有效的方法。有人知道 value_counts 中的默认结构/字典字段名称吗?

(
    df.lazy()
    .with_row_count()
    .with_column(
        pl.when(pl.col("value") == False).then(
            pl.col("row_nr")
            
        ).fill_null(
            strategy = "forward"
        ).alias("id_consecutive_Trues")
    )
    .with_column(
        pl.col("id_consecutive_Trues").value_counts(sort = True)
    )
    .with_column(
        (
            pl.col("id_consecutive_Trues").arr.eval(
                pl.element().struct().rename_fields(["value", "count"]).struct.field("count")
            ).arr.max()
            - pl.lit(1)
        ).alias("max_consecutive_true_values")
    )
    .collect()
)
Run Code Online (Sandbox Code Playgroud)

jqu*_*ous 5

该问题的一种可能的定义是:

\n
    \n
  • 在每组的最后一行true,给出组的长度。
  • \n
\n
df.with_columns(\n   pl.when(pl.col("values") & pl.col("values").is_last())\n     .then(pl.count())\n     .over(pl.col("values").rle_id())\n)\n
Run Code Online (Sandbox Code Playgroud)\n
shape: (10, 2)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 values \xe2\x94\x86 count \xe2\x94\x82\n\xe2\x94\x82 ---    \xe2\x94\x86 ---   \xe2\x94\x82\n\xe2\x94\x82 bool   \xe2\x94\x86 u32   \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 true   \xe2\x94\x86 null  \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 null  \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 3     \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 null  \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 null  \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 1     \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 null  \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 null  \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 null  \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 2     \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

.rle_id()为我们提供连续值的“组 ID”。

\n
df.with_columns(group = pl.col("values").rle_id())\n
Run Code Online (Sandbox Code Playgroud)\n
shape: (10, 2)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 values \xe2\x94\x86 group \xe2\x94\x82\n\xe2\x94\x82 ---    \xe2\x94\x86 ---   \xe2\x94\x82\n\xe2\x94\x82 bool   \xe2\x94\x86 u32   \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 true   \xe2\x94\x86 0     \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 0     \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 0     \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 1     \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 1     \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 2     \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 3     \xe2\x94\x82\n\xe2\x94\x82 false  \xe2\x94\x86 3     \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 4     \xe2\x94\x82\n\xe2\x94\x82 true   \xe2\x94\x86 4     \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

.is_last()允许.over()我们检测每组的最后一行。

\n

pl.count()with.over()给出了组中的行数。

\n