在DataFrame中切换数据类型

11
我试图搜索是否有一种简单地更改带有数字的字符串的数据类型的方法。例如,我面临的问题如下:
df = pl.Dataframe({"foo": 
    ["100CT pen", "pencils 250CT", "what 125CT soever", "this is a thing"]}
)

我可以提取并创建一个名为{"bar": ["100", "250", "125", ""]}的新列。但是,我找不到一个方便的函数将此列转换为Int64或float类型,以便结果为[100, 250, 125, null]
另外,反过来也一样。有时候,拥有一个方便的函数将[100, 250, 125, 0]的列转换为["100", "250", "125", "0"]会很有用。这种功能已经存在了吗?
3个回答

18

完成这个最简单的方法是使用cast表达式。

字符串转为整数/浮点数

将字符串转换为整数(或浮点数)的方式:

import polars as pl

df = pl.DataFrame({"bar": ["100", "250", "125", ""]})
df.with_column(pl.col('bar').cast(pl.Int64, strict=False).alias('bar_int'))

shape: (4, 2)
┌─────┬─────────┐
│ bar ┆ bar_int │
│ --- ┆ ---     │
│ str ┆ i64     │
╞═════╪═════════╡
│ 100100     │
├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 250250     │
├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 125125     │
├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│     ┆ null    │
└─────┴─────────┘

这里有一个方便的可用数据类型列表在这里。所有这些都是别名为polars,所以你可以轻松地引用它们(例如,pl.UInt64)。
对于你描述的数据,我建议使用strict=False,以避免在数百万条记录中出现一个损坏的数字导致异常并停止一切的情况。

整数/浮点数转换为字符串

同样的过程也可以用来将数字转换为字符串 - 在这种情况下,使用utf8数据类型。
让我稍微修改一下你的数据集:
df = pl.DataFrame({"bar": [100.5, 250.25, 1250000, None]})
df.with_column(pl.col("bar").cast(pl.Utf8, strict=False).alias("bar_string"))

shape: (4, 2)
┌────────┬────────────┐
│ bar    ┆ bar_string │
│ ---    ┆ ---        │
│ f64    ┆ str        │
╞════════╪════════════╡
│ 100.5100.5      │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 250.25250.25     │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 1.25e61250000.0  │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ null   ┆ null       │
└────────┴────────────┘

如果您需要更多对格式的控制,您可以使用apply方法和Python的新f-string格式化。
df.with_column(
    pl.col("bar").apply(lambda x: f"This is ${x:,.2f}!").alias("bar_fstring")
)

shape: (4, 2)
┌────────┬────────────────────────┐
│ bar    ┆ bar_fstring            │
│ ---    ┆ ---                    │
│ f64    ┆ str                    │
╞════════╪════════════════════════╡
│ 100.5  ┆ This is $100.50!       │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 250.25 ┆ This is $250.25!       │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 1.25e6 ┆ This is $1,250,000.00! │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ null   ┆ null                   │
└────────┴────────────────────────┘

我发现这个网页对于那些不熟悉f-string格式化的人来说是一个方便的参考。

2
太棒了!我添加了一个额外的答案,展示了如何利用polar格式函数来实现相同的fstring结果,但速度更快。 ;) - ritchie46
1
我认为with_column不再起作用了,我认为现在必须使用with_columns。 - wordsforthewise

10

作为对@cbilot答案的补充。

您不需要使用缓慢的Python lambda函数来使用表达式的特殊字符串格式化。Polars有一个format函数用于此目的:


df = pl.DataFrame({"bar": ["100", "250", "125", ""]})

df.with_columns([
    pl.format("This is {}!", pl.col("bar"))
])

shape: (4, 2)
┌─────┬──────────────┐
│ bar ┆ literal      │
│ --- ┆ ---          │
│ strstr          │
╞═════╪══════════════╡
│ 100 ┆ This is 100! │
├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 250 ┆ This is 250! │
├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 125 ┆ This is 125! │
├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│     ┆ This is !    │
└─────┴──────────────┘


3

对于polars中的其他数据操作,比如字符串转日期时间,请使用strptime()函数。

import polars as pl
df = pl.DataFrame(df_pandas)

df

shape: (100, 2)
┌────────────┬────────┐
│ dates_col  ┆ ticker │
│ ---        ┆ ---    │
│ strstr    │
╞════════════╪════════╡
│ 2022-02-25 ┆ RDW    │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ 2008-05-28 ┆ ARTX   │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ 2015-05-21 ┆ CBAT   │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ 2009-02-09 ┆ ANNB   │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤

像这样使用它,将列转换为字符串:

df.with_column(pl.col("dates_col").str.strptime(pl.Datetime, fmt="%Y-%m-%d").cast(pl.Datetime))

shape: (100, 2)
┌─────────────────────┬────────┐
│ dates_col           ┆ ticker │
│ ---                 ┆ ---    │
│ datetime[μs]        ┆ str    │
╞═════════════════════╪════════╡
│ 2022-02-25 00:00:00 ┆ RDW    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ 2008-05-28 00:00:00 ┆ ARTX   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ 2015-05-21 00:00:00 ┆ CBAT   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ 2009-02-09 00:00:00 ┆ ANNB   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接