极地演员表 pl.反对 pl。Utf8:polars.exceptions.ComputeError:无法强制转换“Object”类型

Polars cast pl.Object to pl.Utf8: polars.exceptions.ComputeError: cannot cast 'Object' type

提问人:Björn 提问时间:11/13/2023 更新时间:11/14/2023 访问量:66

问:

我得到了一个pl。LazyFrame 具有包含日期表示形式的 Object 类型的列,它还包含缺失值 (None)。
在第一步中,我想将列从 转换为 但是,这会导致 ComputeError。我似乎想不通为什么。我想这是由于 None 值,可悲的是我无法在当前时间点删除这些值。
ObjectUtf8

import numpy as np
import polars as pl

rng = np.random.default_rng(12345)
df = pl.LazyFrame(
    data={
        "date": rng.choice(
            [None, "03.04.1998", "03.05.1834", "05.06.2025"], 100
        ),
    }
)
df.with_columns(pl.col("date").cast(pl.Utf8)).collect()
类型转换 python-polars

评论

2赞 jqurious 11/13/2023
当 Polars 分配类型时,它本质上的意思是“我不明白这是什么”——你不能对它们做太多事情。你最初是如何得到这种类型的?Object
0赞 Björn 11/13/2023
我明白了,感谢您对对象 dtype 的解释。因此,在 EDA / First 检查中,检查是否有潜在的我不理解的列可能也是一个好主意。这是单元/压力测试的模型数据。例如,您得到了一个数据库列,该列(错误地但经常被观察到)类型(而不是)包含日期,但也可能包含缺失值。也就是说,我不知道我最终是否会得到这些数据,但这并非不可能df.select(pl.col(pl.Object))VARCHARDATE
1赞 jqurious 11/13/2023
在您的示例中,正在创建一个 numpy 数组。也许改用 Polars 方法是有意义的,这样您就不会遇到这个问题?rng.choice()dtype=objectpl.Series([None, "03.04.1998", "03.05.1834", "05.06.2025"]).sample(100, with_replacement=True)
0赞 Björn 11/13/2023
这成功了,可能是我压力测试的更现实的近似值。非常感谢,也学到了一些东西pl.Object

答:

1赞 ignoring_gravity 11/13/2023 #1

看起来像 Polars 中的一个错误,你能把它报告给他们的 GitHub 吗?

现在,您可以使用tolist

In [24]: import numpy as np
    ...: import polars as pl
    ...:
    ...: rng = np.random.default_rng(12345)
    ...: df = pl.LazyFrame(
    ...:     data={
    ...:         "date": rng.choice(
    ...:             [None, "03.04.1998", "03.05.1834", "05.06.2025"], 100
    ...:         ).tolist(),
    ...:     },
    ...: )

In [25]: df
Out[25]: <LazyFrame [1 col, {"date": Utf8}] at 0x7F6C4A588580>

In [26]: df.collect()
Out[26]:
shape: (100, 1)
┌────────────┐
│ date       │
│ ---        │
│ str        │
╞════════════╡
│ 03.05.1834 │
│ null       │
│ 05.06.2025 │
│ 03.04.1998 │
│ …          │
│ null       │
│ null       │
│ null       │
│ 03.05.1834 │
└────────────┘
1赞 Dean MacGregor 11/14/2023 #2

numpy 和 polars 对待 null 的方式不同,这就是问题所在。

如果你这样做

pl.LazyFrame(
    data={
        "date": rng.choice(
            ["None", "03.04.1998", "03.05.1834", "05.06.2025"], 100
        ),
    }
).with_columns(date=pl.when(pl.col('date')!="None").then(pl.col('date'))).collect()
shape: (100, 1)
┌────────────┐
│ date       │
│ ---        │
│ str        │
╞════════════╡
│ 03.04.1998 │
│ 03.04.1998 │
│ 03.05.1834 │
│ null       │
│ …          │
│ null       │
│ null       │
│ 03.04.1998 │
│ 03.04.1998 │
└────────────┘

1赞 BallpointBen 11/14/2023 #3

强类型 numpy 数组不支持 null 值(浮点数组除外),但您可以使用 解决此问题。首先,我们进行采样,然后构造一个掩码来隐藏值:np.nannp.ma.MaskedArrayNone

import numpy as np

rng = np.random.default_rng(12345)

choices = [None, "03.04.1998", "03.05.1834", "05.06.2025"]
chosen = rng.choice(choices, 100)
mask = [x is None for x in chosen]

arr = np.ma.array(chosen, mask=mask, dtype=str)
>>> arr[:10]
masked_array(data=['03.05.1834', --, '05.06.2025', '03.04.1998', --,
                   '05.06.2025', '03.05.1834', '03.05.1834', '05.06.2025',
                   '03.04.1998'],
             mask=[False,  True, False, False,  True, False, False, False,
                   False, False],
       fill_value='N/A',
            dtype='<U10')

现在 Polars 可以处理这个无效数组:

df = pl.LazyFrame(data={"date": arr})
df.collect()
shape: (100, 1)
┌────────────┐
│ date       │
│ ---        │
│ str        │
╞════════════╡
│ 03.05.1834 │
│ null       │
│ 05.06.2025 │
│ 03.04.1998 │
│ …          │
│ null       │
│ null       │
│ null       │
│ 03.05.1834 │
└────────────┘
2赞 jqurious 11/14/2023 #4

当 Polars 分配类型时,它本质上的意思是:“我不明白这是什么。pl.Object

当你最终得到这种类型时,通常为时已晚,无法用它做任何有用的事情。

在这种特殊情况下,正在创建一个 numpy 数组numpy.random.choicedtype=object

>>> rng.choice([None, "foo"], 3)
array([None, None, 'foo'], dtype=object)

Polars 具有原生的 .sample() 功能,您可以使用它来创建数据。

df = pl.select(date = 
    pl.Series([None, "03.04.1998", "03.05.1834", "05.06.2025"])
      .sample(100, with_replacement=True)
)

# shape: (100, 1)
# ┌────────────┐
# │ date       │
# │ ---        │
# │ str        │
# ╞════════════╡
# │ null       │
# │ 05.06.2025 │
# │ 03.05.1834 │
# │ 03.04.1998 │
# │ …          │
# │ null       │
# │ 03.04.1998 │
# │ 03.05.1834 │
# │ 03.04.1998 │
# └────────────┘