You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars中基于动态周末列生成week_mask并应用add_business_days的实现方法

Polars中基于动态周末列生成week_mask并应用add_business_days的实现方法

我完全懂你遇到的痛点——Polars的dt.add_business_days默认只支持全局统一的week_mask,但你的数据里每一行的周末都不一样,直接传列表达式会触发TypeError,确实挺挠头的。

要解决这个问题,核心是要为每一行生成专属的week_mask,再结合日期和天数计算新日期。因为add_business_days暂时不支持行级的week_mask参数,我们可以用逐行映射的方式来实现,步骤如下:

步骤1:定义星期名称到索引的映射

首先,我们需要把字符串格式的周末名称转换成Polarsweek_mask对应的索引(0=周一, 1=周二...5=周六,6=周日):

weekday_map = {
    "Monday": 0,
    "Tuesday": 1,
    "Wednesday": 2,
    "Thursday": 3,
    "Friday": 4,
    "Saturday": 5,
    "Sunday": 6
}

步骤2:编写行级计算函数

接下来,写一个函数,接收每一行的日期、天数、周末列,生成对应的week_mask后计算新日期:

def compute_custom_business_day(row):
    # 提取行数据
    base_date = row["DT"]
    days_to_add = row["N_DAYS"]
    wknd1 = row["WKND1"]
    wknd2 = row["WKND2"]
    
    # 初始化week_mask:默认所有天都是工作日
    week_mask = [True] * 7
    
    # 标记第一个周末为非工作日
    if wknd1 is not None:
        day_idx = weekday_map[wknd1]
        week_mask[day_idx] = False
    
    # 标记第二个周末(处理null的情况)
    if wknd2 is not None:
        day_idx = weekday_map[wknd2]
        week_mask[day_idx] = False
    
    # 转换为元组后调用add_business_days
    return base_date.dt.add_business_days(days_to_add, week_mask=tuple(week_mask))

步骤3:应用函数到DataFrame

最后,用Polars的struct+map_rows组合,把需要的列打包后逐行计算:

import polars as pl

# 你的原始DataFrame
df = pl.DataFrame([
    ("2025-01-02", 2, "Saturday", "Sunday"),
    ("2025-01-09", 2, "Friday", "Saturday"),
    ("2025-01-10", 2, "Saturday", None),
    ("2025-01-15", 1, "Saturday", "Sunday"),
], schema=["DT", "N_DAYS", "WKND1", "WKND2"], orient="row")
df = df.with_columns(pl.col("DT").str.to_date())

# 计算新日期
df = df.with_columns(
    pl.struct(["DT", "N_DAYS", "WKND1", "WKND2"])
    .map_rows(compute_custom_business_day)
    .alias("NEW_DT")
)

验证结果

运行后得到的结果和你期望的完全一致:

┌────────────┬────────┬──────────┬──────────┬────────────┐
│ DT         ┆ N_DAYS ┆ WKND1    ┆ WKND2    ┆ NEW_DT     │
│ ---        ┆ ---    ┆ ---      ┆ ---      ┆ ---        │
│ date       ┆ i64    ┆ str      ┆ str      ┆ date       │
╞════════════╪════════╪══════════╪══════════╪════════════╡
│ 2025-01-02 ┆ 2      ┆ Saturday ┆ Sunday   ┆ 2025-01-06 │
│ 2025-01-09 ┆ 2      ┆ Friday   ┆ Saturday ┆ 2025-01-14 │
│ 2025-01-10 ┆ 2      ┆ Saturday ┆ null     ┆ 2025-01-13 │
│ 2025-01-15 ┆ 1      ┆ Saturday ┆ Sunday   ┆ 2025-01-16 │
└────────────┴────────┴──────────┴──────────┴────────────┘

补充说明

  • 如果你的数据集非常大,map_rows的性能可能会不如向量化操作,但目前Polars的add_business_days还不支持行级的week_mask参数,这种方法是最直接的解决方案。
  • 代码里已经处理了WKND2为null的情况,比如第三行只会标记周六为非工作日。

备注:内容来源于stack exchange,提问作者Greg Vaysman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 14:28:03