在现有列名中替换字符而不创建新列

3 投票
1 回答
47 浏览
提问于 2025-04-12 17:41

我正在读取一个csv文件,并且需要规范化列名,这个操作是更大功能链的一部分。我想要通过功能链来完成所有的操作。

当我使用推荐的 name.map 函数来替换列中的字符,比如:

import polars as pl

df = pl.DataFrame(
    {"A (%)": [1, 2, 3], "B": [4, 5, 6], "C (Euro)": ["abc", "def", "ghi"]}
).with_columns(
    pl.all().name.map(
        lambda c: c.replace(" ", "_")
        .replace("(%)", "pct")
        .replace("(Euro)", "euro")
        .lower()
    )
)
df.head()

我得到的是

shape: (3, 6)
┌───────┬─────┬──────────┬───────┬─────┬────────┐
│ A (%) ┆ B   ┆ C (Euro) ┆ a_pct ┆ b   ┆ c_euro │
│ ---   ┆ --- ┆ ---      ┆ ---   ┆ --- ┆ ---    │
│ i64   ┆ i64 ┆ str      ┆ i64   ┆ i64 ┆ str    │
╞═══════╪═════|══════════╡═══════╡═════╡════════╡
│ 1     ┆ 4   ┆ "abc"    ┆ 1     ┆ 4   ┆ "abc"  │
│ 2     ┆ 5   ┆ "def"    ┆ 2     ┆ 5   ┆ "def"  │
│ 3     ┆ 6   ┆ "ghi"    ┆ 3     ┆ 6   ┆"ghi"   │
└───────┴─────┴──────────┴───────┴─────┴────────┘

而不是我预期的

shape: (3, 3)
┌───────┬─────┬────────┐
│ a_pct ┆ b   ┆ c_euro │
│ ---   ┆ --- ┆ ---    │ 
│ i64   ┆ i64 ┆ str    │
╞═══════╪═════|════════╡
│ 1     ┆ 4   ┆ "abc"  │
│ 2     ┆ 5   ┆ "def"  │
│ 3     ┆ 6   ┆ "ghi"  │
└───────┴─────┴────────┘

?

我该如何在不创建新列的情况下,通过功能链来替换现有列名中的特定字符呢?

1 个回答

3

你可以简单地把 DataFrame.with_columns() 替换成 DataFrame.select() 方法:

df = pl.DataFrame(
    {"A (%)": [1, 2, 3], "B": [4, 5, 6], "C (Euro)": ["abc", "def", "ghi"]}
).select(
    pl.all().name.map(
        lambda c: c.replace(" ", "_")
        .replace("(%)", "pct")
        .replace("(Euro)", "euro")
        .lower()
    )
)

┌───────┬─────┬────────┐
│ a_pct ┆ b   ┆ c_euro │
│ ---   ┆ --- ┆ ---    │
│ i64   ┆ i64 ┆ str    │
╞═══════╪═════╪════════╡
│ 1     ┆ 4   ┆ abc    │
│ 2     ┆ 5   ┆ def    │
│ 3     ┆ 6   ┆ ghi    │
└───────┴─────┴────────┘

需要特别说明的是(正如Dean MacGregor在评论中提到的),DataFrame.with_columns() 总是会向数据表中添加新列。 虽然新列的名字可能和原来的列一样,但如果名字相同,原来的列就会被新列替换。你可以在文档中看到这一点:

向这个数据表添加列。

添加的列会替换掉名字相同的现有列。

DataFrame.select() 则是用来选择数据表中已经存在的列。

另外,如果你只是想重命名所有的列,使用 DataFrame.rename() 可能会更自然一些:

...
.rename(
    lambda c: c.replace(" ", "_")
        .replace("(%)", "pct")
        .replace("(Euro)", "euro")
        .lower()
)

┌───────┬─────┬────────┐
│ a_pct ┆ b   ┆ c_euro │
│ ---   ┆ --- ┆ ---    │
│ i64   ┆ i64 ┆ str    │
╞═══════╪═════╪════════╡
│ 1     ┆ 4   ┆ abc    │
│ 2     ┆ 5   ┆ def    │
│ 3     ┆ 6   ┆ ghi    │
└───────┴─────┴────────┘

撰写回答