极地 YYYY 周进入日期

问题描述 投票:0回答:2

有人知道如何将 YYYY Week 解析为 Polars 中的日期列吗?
我已经尝试过这段代码,但它抛出一个错误。

import polars as pl

pl.DataFrame({
    "week": [201901, 201902, 201903, 201942, 201943, 201944]
}).with_columns(pl.col("week").cast(pl.String).str.to_date("%Y%U").alias("date"))
InvalidOperationError: conversion from `str` to `date` failed in column 'week' 
for 6 out of 6 values: ["201901", "201902", … "201944"]
python date python-polars
2个回答
4
投票

这似乎是一个错误(尽管它与底层的 rust 包 chrono 而不是 Polars 本身有关)。 我尝试使用基本Python的strptime,它忽略了

%U
,只给出了所有情况下的第一年,所以你可以像这样进行字符串操作和数学(假设你不需要精确的响应)

pl.DataFrame({
    "week": [201901, 201902, 201903, 201942, 201943, 201944]
}) \
    .with_columns(pl.col('week').cast(pl.Utf8)) \
    .with_columns([pl.col('week').str.slice(0,4).cast(pl.Int32).alias('year'),
                   pl.col('week').str.slice(4,2).cast(pl.Int32).alias('week')]) \
    .select(pl.date(pl.col('year'),1,1) + pl.duration(days=(pl.col('week')-1)*7).alias('date'))

如果你看一下 %U 的定义,它应该基于一年中的第 x 个星期日,而我的数学只是乘以 7。

另一种方法是对日期进行 df,然后对它们进行 strftime,然后加入 dfs。 所以可能是这样的:

dfdates=pl.DataFrame({'date':pl.date_range(datetime(2019,1,1), datetime(2019,12,31),'1d').cast(pl.Date())}) \
        .with_columns(pl.col('date').dt.strftime("%Y%U").alias('week')) \
        .groupby('week').agg(pl.col('date').min())

然后将其与你拥有的结合起来

pl.DataFrame({
    "week": [201901, 201902, 201903, 201942, 201943, 201944]
}).with_columns(pl.col('week').cast(pl.Utf8())).join(dfdates, on='week')

shape: (6, 2)
┌────────┬────────────┐
│ week   ┆ date       │
│ ---    ┆ ---        │
│ str    ┆ date       │
╞════════╪════════════╡
│ 201903 ┆ 2019-01-20 │
│ 201944 ┆ 2019-11-03 │
│ 201902 ┆ 2019-01-13 │
│ 201943 ┆ 2019-10-27 │
│ 201942 ┆ 2019-10-20 │
│ 201901 ┆ 2019-01-06 │
└────────┴────────────┘

0
投票

这真的很奇怪,伙计,看起来只有 2019 年的日期被破坏了,看看我下面的例子:

pl.DataFrame(
    {
        "week": [
            202201,
            202202,
            202203,
            202242,
            202243,
            202244,
            202101,
            202102,
            202103,
            202142,
            202143,
            202144,
            201901,
            201902,
            201903,
            201942,
            201943,
            201944,
            201801,
            201802,
            201803,
            201842,
            201843,
            201844,
        ]
    }
).with_columns(pl.format("{}0", "week")).with_columns(
    pl.col("week").str.strptime(pl.Date, fmt="%Y%W%w", strict=False).alias("teste")
)

shape: (24, 2)
┌─────────┬────────────┐
│ week    ┆ teste      │
│ ---     ┆ ---        │
│ str     ┆ date       │
╞═════════╪════════════╡
│ 2022010 ┆ 2022-01-09 │
│ 2022020 ┆ 2022-01-16 │
│ 2022030 ┆ 2022-01-23 │
│ 2022420 ┆ 2022-10-23 │
│ 2022430 ┆ 2022-10-30 │
│ 2022440 ┆ 2022-11-06 │
│ 2021010 ┆ 2021-01-10 │
│ 2021020 ┆ 2021-01-17 │
│ 2021030 ┆ 2021-01-24 │
│ 2021420 ┆ 2021-10-24 │
│ 2021430 ┆ 2021-10-31 │
│ 2021440 ┆ 2021-11-07 │
│ 2019010 ┆ null       │
│ 2019020 ┆ null       │
│ 2019030 ┆ null       │
│ 2019420 ┆ null       │
│ 2019430 ┆ null       │
│ 2019440 ┆ null       │
│ 2018010 ┆ 2018-01-07 │
│ 2018020 ┆ 2018-01-14 │
│ 2018030 ┆ 2018-01-21 │
│ 2018420 ┆ 2018-10-21 │
│ 2018430 ┆ 2018-10-28 │
│ 2018440 ┆ 2018-11-04 │
└─────────┴────────────┘

除了错误之外,我总是使用以下表达式将周计数解析为正确的日期

.with_columns(pl.format("{}0", "week")).with_columns(pl.col("week").str.strptime(pl.Date, fmt="%Y%W%w", strict=False)

重要的是要注意,有必要连接工作日,才能真正解析此模式,我认为其他帖子评论中提到了这一点。

© www.soinside.com 2019 - 2024. All rights reserved.