在现有列名中替换字符而不创建新列
我正在读取一个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 │
└───────┴─────┴────────┘