在与polars数据框链式表达式时,with_columns_seq操作出现ComputeError
我正在尝试对一个懒加载的polars数据框中的单列进行一系列操作,但我想避免重复使用with_columns_seq
。然而,我遇到了一个ComputeError
,提示有重复的列名。有没有更好的方法可以解决这个问题呢?
df = (
df
.with_columns_seq([
pl.col('sentiment').cast(pl.UInt8),
pl.col('review').map_elements(lambda x: BeautifulSoup(x).get_text()),
pl.col('review').str.replace(r"[^a-zA-Z0-9]", " "),
pl.col('review').str.to_lowercase(),
# pl.col('review').str.split_by(' ')
])
)
df.collect().head()
而且错误信息是
ComputeError: the name: 'review' passed to `LazyFrame.with_columns` is duplicate
It's possible that multiple expressions are returning the same default column name. If this is the case, try renaming the columns with `.alias("new_name")` to avoid duplicate column names.
我试着把所有操作组合在一起,但因为重复的列名出错了。
1 个回答
4
解释
你的错误信息几乎已经告诉你问题的所有内容:
可能有多个表达式返回了相同的默认列名。如果是这种情况,尝试用
.alias("new_name")
来重命名列,以避免重复的列名。
不过,这里并没有给出你可能想要的解决方案。
错误的原因是每一行以 pl.col("review")
开头的代码都会创建一个新的 review
列,因为 .with_columns_seq
并不是说你一个接一个地运行这些表达式来更新数据。它只是意味着没有使用并行处理来完成这个操作,你完全可以使用 with_columns
。
通常的解决办法是使用 alias("new_name")
,就像错误信息中提到的那样。但在你的情况下,这样做只会创建两个数据稍有不同的列。
.with_columns_seq([
pl.col('review').map_elements(lambda x: x),
pl.col('review').str.to_lowercase().alias("lowercase"),
])
┌───────────┬──────────────────────┬──────────────────────┐
│ sentiment ┆ review ┆ lowercase │
│ --- ┆ --- ┆ --- │
│ i64 ┆ str ┆ str │
╞═══════════╪══════════════════════╪══════════════════════╡
│ 1 ┆ I love this movie ┆ i love this movie │
│ 0 ┆ I hate this movie!! ┆ i hate this movie!! │
...
这似乎不是你想要的。相反,你需要一种方法来顺序地对新的 review
列执行每一个操作。
解决方案
要顺序地运行这些针对 review
的表达式,你需要 将它们连接起来。
表达式的强大之处在于每个表达式都会产生一个新的表达式,并且它们可以连接在一起。你可以通过将表达式传递给 Polars 的执行上下文来运行它们。
所以你应该这样做:
df = (
df
.with_columns([
pl.col('sentiment').cast(pl.UInt8),
pl.col('review').map_elements(lambda x: BeautifulSoup(x).get_text())
.str.replace_all(r"[^a-zA-Z0-9]", " ")
.str.to_lowercase()
])
)