Skip to content

Commit

Permalink
feat(python): allow df.rename and lf.rename to take a renaming functi…
Browse files Browse the repository at this point in the history
…on (pola-rs#13708)

Co-authored-by: Wainberg <m.wainberg@utoronto.ca>
  • Loading branch information
2 people authored and r-brink committed Jan 24, 2024
1 parent 3bec1da commit d51136e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
16 changes: 14 additions & 2 deletions py-polars/polars/dataframe/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -4059,14 +4059,15 @@ def reverse(self) -> DataFrame:
"""
return self.select(F.col("*").reverse())

def rename(self, mapping: dict[str, str]) -> DataFrame:
def rename(self, mapping: dict[str, str] | Callable[[str], str]) -> DataFrame:
"""
Rename column names.
Parameters
----------
mapping
Key value pairs that map from old name to new name.
Key value pairs that map from old name to new name, or a function
that takes the old name as input and returns the new name.
Examples
--------
Expand All @@ -4084,6 +4085,17 @@ def rename(self, mapping: dict[str, str]) -> DataFrame:
│ 2 ┆ 7 ┆ b │
│ 3 ┆ 8 ┆ c │
└───────┴─────┴─────┘
>>> df.rename(lambda column_name: "c" + column_name[1:])
shape: (3, 3)
┌─────┬─────┬─────┐
│ coo ┆ car ┆ cam │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str │
╞═════╪═════╪═════╡
│ 1 ┆ 6 ┆ a │
│ 2 ┆ 7 ┆ b │
│ 3 ┆ 8 ┆ c │
└─────┴─────┴─────┘
"""
return self.lazy().rename(mapping).collect(_eager=True)

Expand Down
25 changes: 20 additions & 5 deletions py-polars/polars/lazyframe/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -4165,14 +4165,15 @@ def drop(
drop_cols = _expand_selectors(self, *columns)
return self._from_pyldf(self._ldf.drop(drop_cols))

def rename(self, mapping: dict[str, str]) -> Self:
def rename(self, mapping: dict[str, str] | Callable[[str], str]) -> Self:
"""
Rename column names.
Parameters
----------
mapping
Key value pairs that map from old name to new name.
Key value pairs that map from old name to new name, or a function
that takes the old name as input and returns the new name.
Notes
-----
Expand All @@ -4199,10 +4200,24 @@ def rename(self, mapping: dict[str, str]) -> Self:
│ 2 ┆ 7 ┆ b │
│ 3 ┆ 8 ┆ c │
└───────┴─────┴─────┘
>>> lf.rename(lambda column_name: "c" + column_name[1:]).collect()
shape: (3, 3)
┌─────┬─────┬─────┐
│ coo ┆ car ┆ cam │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str │
╞═════╪═════╪═════╡
│ 1 ┆ 6 ┆ a │
│ 2 ┆ 7 ┆ b │
│ 3 ┆ 8 ┆ c │
└─────┴─────┴─────┘
"""
existing = list(mapping.keys())
new = list(mapping.values())
return self._from_pyldf(self._ldf.rename(existing, new))
if callable(mapping):
return self.select(F.all().name.map(mapping))
else:
existing = list(mapping.keys())
new = list(mapping.values())
return self._from_pyldf(self._ldf.rename(existing, new))

def reverse(self) -> Self:
"""
Expand Down
6 changes: 6 additions & 0 deletions py-polars/tests/unit/dataframe/test_df.py
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,12 @@ def test_rename(df: pl.DataFrame) -> None:
_ = out[["foos", "bars"]]


def test_rename_lambda() -> None:
df = pl.DataFrame({"a": [1], "b": [2], "c": [3]})
out = df.rename(lambda col: "foo" if col == "a" else "bar" if col == "b" else col)
assert out.columns == ["foo", "bar", "c"]


def test_write_csv() -> None:
df = pl.DataFrame(
{
Expand Down
8 changes: 8 additions & 0 deletions py-polars/tests/unit/test_lazy.py
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,14 @@ def test_with_column_renamed(fruits_cars: pl.DataFrame) -> None:
assert res.columns[0] == "C"


def test_rename_lambda() -> None:
ldf = pl.LazyFrame({"a": [1], "b": [2], "c": [3]})
out = ldf.rename(
lambda col: "foo" if col == "a" else "bar" if col == "b" else col
).collect()
assert out.columns == ["foo", "bar", "c"]


def test_reverse() -> None:
out = pl.LazyFrame({"a": [1, 2], "b": [3, 4]}).reverse()
expected = pl.DataFrame({"a": [2, 1], "b": [4, 3]})
Expand Down

0 comments on commit d51136e

Please sign in to comment.