From e20356cd6f4ee183cfddae7b726de26d0ceb0fa4 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Tue, 9 Jul 2024 12:26:49 -0700 Subject: [PATCH 1/3] Initial commit --- python/cudf/cudf/pandas/_wrappers/pandas.py | 11 ++++++++++- python/cudf/cudf/pandas/fast_slow_proxy.py | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/python/cudf/cudf/pandas/_wrappers/pandas.py b/python/cudf/cudf/pandas/_wrappers/pandas.py index dd6f6fe76ba..a35f9d80ee2 100644 --- a/python/cudf/cudf/pandas/_wrappers/pandas.py +++ b/python/cudf/cudf/pandas/_wrappers/pandas.py @@ -285,6 +285,11 @@ def Index__new__(cls, *args, **kwargs): }, ) + +def name(self): + return self._fsproxy_wrapped.name_ + + RangeIndex = make_final_proxy_type( "RangeIndex", cudf.RangeIndex, @@ -292,7 +297,11 @@ def Index__new__(cls, *args, **kwargs): fast_to_slow=lambda fast: fast.to_pandas(), slow_to_fast=cudf.from_pandas, bases=(Index,), - additional_attributes={"__init__": _DELETE}, + additional_attributes={ + "__init__": _DELETE, + "name_": None, + "name": property(name), + }, ) SparseDtype = make_final_proxy_type( diff --git a/python/cudf/cudf/pandas/fast_slow_proxy.py b/python/cudf/cudf/pandas/fast_slow_proxy.py index dfb729cae6b..f6358c009ea 100644 --- a/python/cudf/cudf/pandas/fast_slow_proxy.py +++ b/python/cudf/cudf/pandas/fast_slow_proxy.py @@ -526,6 +526,8 @@ def __setattr__(self, name, value): if name.startswith("_"): object.__setattr__(self, name, value) return + if name == "name": + self._fsproxy_wrapped.name_ = value return _FastSlowAttribute("__setattr__").__get__(self, type(self))( name, value ) From 604d107f62cd85597e4e030d9039943e29859dc4 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Wed, 10 Jul 2024 07:49:57 -0700 Subject: [PATCH 2/3] Add a test --- python/cudf/cudf/pandas/_wrappers/pandas.py | 51 ++++++++++++++++--- python/cudf/cudf/pandas/fast_slow_proxy.py | 2 - .../cudf_pandas_tests/test_cudf_pandas.py | 40 +++++++++++++++ 3 files changed, 83 insertions(+), 10 deletions(-) diff --git a/python/cudf/cudf/pandas/_wrappers/pandas.py b/python/cudf/cudf/pandas/_wrappers/pandas.py index 1807d411b31..d3a3488081a 100644 --- a/python/cudf/cudf/pandas/_wrappers/pandas.py +++ b/python/cudf/cudf/pandas/_wrappers/pandas.py @@ -260,6 +260,23 @@ def Index__new__(cls, *args, **kwargs): return self +def name(self): + return self._fsproxy_wrapped._name + + +def Index__setattr__(self, name, value): + if name.startswith("_"): + object.__setattr__(self, name, value) + return + if name == "name": + setattr(self._fsproxy_wrapped, "_name", value) + if name == "names": + setattr(self._fsproxy_wrapped, "_names", value) + return _FastSlowAttribute("__setattr__").__get__(self, type(self))( + name, value + ) + + Index = make_final_proxy_type( "Index", cudf.Index, @@ -277,19 +294,16 @@ def Index__new__(cls, *args, **kwargs): "__iter__": custom_iter, "__init__": _DELETE, "__new__": Index__new__, + "__setattr__": Index__setattr__, "_constructor": _FastSlowAttribute("_constructor"), "__array_ufunc__": _FastSlowAttribute("__array_ufunc__"), "_accessors": set(), "_data": _FastSlowAttribute("_data", private=True), "_mask": _FastSlowAttribute("_mask", private=True), + "name": property(name), }, ) - -def name(self): - return self._fsproxy_wrapped.name_ - - RangeIndex = make_final_proxy_type( "RangeIndex", cudf.RangeIndex, @@ -299,7 +313,7 @@ def name(self): bases=(Index,), additional_attributes={ "__init__": _DELETE, - "name_": None, + "__setattr__": Index__setattr__, "name": property(name), }, ) @@ -328,7 +342,11 @@ def name(self): fast_to_slow=lambda fast: fast.to_pandas(), slow_to_fast=cudf.from_pandas, bases=(Index,), - additional_attributes={"__init__": _DELETE}, + additional_attributes={ + "__init__": _DELETE, + "__setattr__": Index__setattr__, + "name": property(name), + }, ) Categorical = make_final_proxy_type( @@ -359,6 +377,8 @@ def name(self): "__init__": _DELETE, "_data": _FastSlowAttribute("_data", private=True), "_mask": _FastSlowAttribute("_mask", private=True), + "__setattr__": Index__setattr__, + "name": property(name), }, ) @@ -394,6 +414,8 @@ def name(self): "__init__": _DELETE, "_data": _FastSlowAttribute("_data", private=True), "_mask": _FastSlowAttribute("_mask", private=True), + "__setattr__": Index__setattr__, + "name": property(name), }, ) @@ -450,6 +472,8 @@ def name(self): "__init__": _DELETE, "_data": _FastSlowAttribute("_data", private=True), "_mask": _FastSlowAttribute("_mask", private=True), + "__setattr__": Index__setattr__, + "name": property(name), }, ) @@ -483,6 +507,11 @@ def name(self): additional_attributes={"__hash__": _FastSlowAttribute("__hash__")}, ) + +def names(self): + return self._fsproxy_wrapped._names + + MultiIndex = make_final_proxy_type( "MultiIndex", cudf.MultiIndex, @@ -490,7 +519,11 @@ def name(self): fast_to_slow=lambda fast: fast.to_pandas(), slow_to_fast=cudf.from_pandas, bases=(Index,), - additional_attributes={"__init__": _DELETE}, + additional_attributes={ + "__init__": _DELETE, + "__setattr__": Index__setattr__, + "name": property(names), + }, ) TimeGrouper = make_intermediate_proxy_type( @@ -678,6 +711,8 @@ def name(self): "__init__": _DELETE, "_data": _FastSlowAttribute("_data", private=True), "_mask": _FastSlowAttribute("_mask", private=True), + "__setattr__": Index__setattr__, + "name": property(name), }, ) diff --git a/python/cudf/cudf/pandas/fast_slow_proxy.py b/python/cudf/cudf/pandas/fast_slow_proxy.py index f6358c009ea..dfb729cae6b 100644 --- a/python/cudf/cudf/pandas/fast_slow_proxy.py +++ b/python/cudf/cudf/pandas/fast_slow_proxy.py @@ -526,8 +526,6 @@ def __setattr__(self, name, value): if name.startswith("_"): object.__setattr__(self, name, value) return - if name == "name": - self._fsproxy_wrapped.name_ = value return _FastSlowAttribute("__setattr__").__get__(self, type(self))( name, value ) diff --git a/python/cudf/cudf_pandas_tests/test_cudf_pandas.py b/python/cudf/cudf_pandas_tests/test_cudf_pandas.py index bc864a48e9d..de308a4cd16 100644 --- a/python/cudf/cudf_pandas_tests/test_cudf_pandas.py +++ b/python/cudf/cudf_pandas_tests/test_cudf_pandas.py @@ -1592,3 +1592,43 @@ def test_at_setitem_empty(): df.at[0, "new"] = 2.0 expected = pd.DataFrame({"name": [1.0], "new": [2.0]}) tm.assert_frame_equal(df, expected) + + +@pytest.mark.parametrize( + "index", + [ + xpd.Index([1, 2, 3], name="foo"), + xpd.Index(["a", "b", "c"], name="foo"), + xpd.RangeIndex(start=0, stop=3, step=1, name="foo"), + xpd.CategoricalIndex(["a", "b", "a"], name="foo"), + xpd.DatetimeIndex( + ["2024-04-24", "2025-04-24", "2026-04-24"], name="foo" + ), + xpd.TimedeltaIndex(["1 days", "2 days", "3 days"], name="foo"), + xpd.PeriodIndex( + ["2024-06", "2023-06", "2022-06"], freq="M", name="foo" + ), + xpd.IntervalIndex.from_breaks([0, 1, 2, 3], name="foo"), + pd.MultiIndex.from_tuples( + [(1, "a"), (2, "b"), (3, "c")], names=["foo1", "bar1"] + ), + ], +) +def test_change_index_name(index): + s = xpd.Series([1, 2, object()], index=index) + df = xpd.DataFrame({"values": [1, 2, object()]}, index=index) + + if isinstance(index, xpd.MultiIndex): + names = ["foo2", "bar2"] + s.index.names = names + df.index.names = names + + assert s.index.names == names + assert df.index.names == names + else: + name = "bar" + s.index.name = name + df.index.name = name + + assert s.index.name == name + assert df.index.name == name From 3604ce3b27964cc6ea36a5b26cc91bfd4e8703e7 Mon Sep 17 00:00:00 2001 From: Matthew Murray Date: Wed, 10 Jul 2024 08:36:09 -0700 Subject: [PATCH 3/3] Fix typo xpd not pd --- python/cudf/cudf_pandas_tests/test_cudf_pandas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/cudf/cudf_pandas_tests/test_cudf_pandas.py b/python/cudf/cudf_pandas_tests/test_cudf_pandas.py index de308a4cd16..6292022d8e4 100644 --- a/python/cudf/cudf_pandas_tests/test_cudf_pandas.py +++ b/python/cudf/cudf_pandas_tests/test_cudf_pandas.py @@ -1609,7 +1609,7 @@ def test_at_setitem_empty(): ["2024-06", "2023-06", "2022-06"], freq="M", name="foo" ), xpd.IntervalIndex.from_breaks([0, 1, 2, 3], name="foo"), - pd.MultiIndex.from_tuples( + xpd.MultiIndex.from_tuples( [(1, "a"), (2, "b"), (3, "c")], names=["foo1", "bar1"] ), ],