如何在python-polars中从字符串列中删除最后N个字符?

3
给定这个数据框:
df = pl.DataFrame({"s": ["pear", None, "papaya", "dragonfruit"]})

我想要删除最后X个字符,例如删除列中的最后2个字符。 显然,这并不是我想要的结果。
df.with_columns(   
    pl.col("s").str.slice(2).alias("s_sliced"),

)

我希望结果是:
shape: (4, 2)
┌─────────────┬──────────┐
│ s           ┆ s_sliced │
│ ---         ┆ ---      │
│ str         ┆ str      │
╞═════════════╪══════════╡
│ pear        ┆ pe       │
│ null        ┆ null     │
│ papaya      ┆ papa     │
│ dragonfruit ┆ dragonfru|  
2个回答

3
你可以使用正则表达式与 .str.replace
  • . 匹配一个 "单个字符"
  • $ 匹配 "结尾"
  • {N} 精确匹配 N 次
意思是我们可以使用 ..$.{2}$
df.with_columns(   
    pl.col("s").str.replace(r"..$", "").alias("s_sliced"),
)

shape: (4, 2)
┌─────────────┬───────────┐
│ s           ┆ s_sliced  │
│ ---         ┆ ---       │
│ str         ┆ str       │
╞═════════════╪═══════════╡
│ pear        ┆ pe        │
│ null        ┆ null      │
│ papaya      ┆ papa      │
│ dragonfruit ┆ dragonfru │
└─────────────┴───────────┘

0
一种非正则表达式的方法来做这个相当丑陋,但是下面就是它...
df.with_columns(
    s_sliced=(pl.col('s').str.explode().implode().over('s')
                .list.take(pl.arange(0,(pl.col('s').str.n_chars()-2))))
            .list.eval(pl.element().str.concat("")).list.get(0))

首先要注意的是,我们正在使用str.explode.implode将字符列转换为列表,这是因为str.slice不接受长度表达式,而pl.arange则可以。然后我们只需要取出我们想要的元素,即除了最后两个元素之外的所有元素。最后,我们需要将列表转换回字符串。
** 有一个非常简洁的答案使用了一个简单的正则表达式,但是它的作者已经删除了,我不愿意复制它。也许帖子的作者会恢复它。

谢谢Dean - 经过重新考虑,我不确定建议使用正则表达式是否是正确的方法。 - undefined
1
@jqurious 是的,在基本的Python中,你可以直接使用s[0:-2]来实现,我相信你已经知道。但是Polars的切片不够灵活,所以正则表达式肯定是最容易阅读的方法。之前有一个类似的问题这里,针对列表的。 - undefined
谢谢问题链接。是的,我以为可能存在 .str.head / .str.tail 这样的函数来模仿其他的头部/尾部函数。 - undefined

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