Repository: modin-project/modin

Issue:
PERF: avoid default_to_pandas in ``Series.cat.codes``, ``Series.dt.tz``, and ``Series.dt.to_pytimedelta``
Placeholder.


Discussion:

Resolving patch:
diff --git a/modin/core/dataframe/algebra/default2pandas/default.py b/modin/core/dataframe/algebra/default2pandas/default.py
--- a/modin/core/dataframe/algebra/default2pandas/default.py
+++ b/modin/core/dataframe/algebra/default2pandas/default.py
@@ -87,14 +87,18 @@ def applyier(df, *args, **kwargs):
                 and func != "to_numpy"
                 and func != pandas.DataFrame.to_numpy
             ):
-                # When applying a DatetimeProperties function, if we don't
-                # specify the dtype for the DataFrame, the frame might get the
-                # wrong dtype, e.g. for to_pydatetime in
+                # When applying a DatetimeProperties or TimedeltaProperties function,
+                # if we don't specify the dtype for the DataFrame, the frame might
+                # get the wrong dtype, e.g. for to_pydatetime in
                 # https://github.com/modin-project/modin/issues/4436
                 astype_kwargs = {}
                 dtype = getattr(result, "dtype", None)
                 if dtype and isinstance(
-                    df, pandas.core.indexes.accessors.DatetimeProperties
+                    df,
+                    (
+                        pandas.core.indexes.accessors.DatetimeProperties,
+                        pandas.core.indexes.accessors.TimedeltaProperties,
+                    ),
                 ):
                     astype_kwargs["dtype"] = dtype
                 result = (
diff --git a/modin/core/storage_formats/pandas/query_compiler.py b/modin/core/storage_formats/pandas/query_compiler.py
--- a/modin/core/storage_formats/pandas/query_compiler.py
+++ b/modin/core/storage_formats/pandas/query_compiler.py
@@ -3252,7 +3252,12 @@ def sort_columns_by_row_values(self, rows, ascending=True, **kwargs):
 
     # Cat operations
     def cat_codes(self):
-        return self.default_to_pandas(lambda df: df[df.columns[0]].cat.codes)
+        def func(df) -> np.ndarray:
+            ser = df.iloc[:, 0]
+            return ser.cat.codes
+
+        res = self._modin_frame.apply_full_axis(axis=0, func=func)
+        return self.__constructor__(res)
 
     # END Cat operations
 
diff --git a/modin/pandas/series_utils.py b/modin/pandas/series_utils.py
--- a/modin/pandas/series_utils.py
+++ b/modin/pandas/series_utils.py
@@ -16,7 +16,7 @@
 
 Accessors: `Series.cat`, `Series.str`, `Series.dt`
 """
-
+from typing import TYPE_CHECKING
 import sys
 import numpy as np
 import pandas
@@ -31,6 +31,10 @@
     # Python <= 3.6
     from re import _pattern_type
 
+if TYPE_CHECKING:
+    from datetime import tzinfo
+    from pandas._typing import npt
+
 
 @_inherit_docstrings(pandas.core.arrays.categorical.CategoricalAccessor)
 class CategoryMethods(ClassLogger):
@@ -565,8 +569,11 @@ def days_in_month(self):
         return Series(query_compiler=self._query_compiler.dt_days_in_month())
 
     @property
-    def tz(self):
-        return self._query_compiler.dt_tz().to_pandas().squeeze()
+    def tz(self) -> "tzinfo | None":
+        dtype = self._series.dtype
+        if isinstance(dtype, np.dtype):
+            return None
+        return dtype.tz
 
     @property
     def freq(self):
@@ -616,10 +623,9 @@ def total_seconds(self, *args, **kwargs):
             query_compiler=self._query_compiler.dt_total_seconds(*args, **kwargs)
         )
 
-    def to_pytimedelta(self):
-        return self._query_compiler.default_to_pandas(
-            lambda df: pandas.Series.dt.to_pytimedelta(df.squeeze(axis=1).dt)
-        )
+    def to_pytimedelta(self) -> "npt.NDArray[np.object_]":
+        res = self._query_compiler.dt_to_pytimedelta()
+        return res.to_numpy()[:, 0]
 
     @property
     def seconds(self):


Test patch: