Repository: modin-project/modin

Issue:
`reindex` doesn't preserve index metadata
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: `Windows 10`
- **Modin version** (`modin.__version__`): 830e8dcea0f05118e4a2b66d66ed42dce9b84d5a
- **Python version**: `3.8.10`
- **Code we can use to reproduce**:

```python
import modin.pandas as pd

index = pd.date_range(end="1/1/2018", periods=3, freq="h", name="some meta") 
df = pd.DataFrame([1,2,3], index=index)

new_index = list(reversed(df.index))
print(df.reindex(new_index).index)
# DatetimeIndex(['2018-01-01 00:00:00', '2017-12-31 23:00:00',
#                '2017-12-31 22:00:00'],
#              dtype='datetime64[ns]', freq=None)
```

<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
<!-- Describe the problem clearly here. -->

When using pandas the index looks like:
```python
>>> print(df.reindex(new_index).index)
DatetimeIndex(['2018-01-01 00:00:00', '2017-12-31 23:00:00',
               '2017-12-31 22:00:00'],
              dtype='datetime64[ns]', name='some meta', freq=None)
```

### Source code / logs
<!-- Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. -->



Discussion:

Resolving patch:
diff --git a/modin/pandas/base.py b/modin/pandas/base.py
--- a/modin/pandas/base.py
+++ b/modin/pandas/base.py
@@ -26,6 +26,7 @@
     is_dtype_equal,
     is_object_dtype,
 )
+from pandas.core.indexes.api import ensure_index
 import pandas.core.window.rolling
 import pandas.core.resample
 import pandas.core.generic
@@ -2213,6 +2214,34 @@ def rank(
             )
         )
 
+    def _copy_index_metadata(self, source, destination):  # noqa: PR01, RT01, D200
+        """
+        Copy Index metadata from `source` to `destination` inplace.
+        """
+        if hasattr(source, "name") and hasattr(destination, "name"):
+            destination.name = source.name
+        if hasattr(source, "names") and hasattr(destination, "names"):
+            destination.names = source.names
+        return destination
+
+    def _ensure_index(self, index_like, axis=0):  # noqa: PR01, RT01, D200
+        """
+        Ensure that we have an index from some index-like object.
+        """
+        if (
+            self._query_compiler.has_multiindex(axis=axis)
+            and not isinstance(index_like, pandas.Index)
+            and is_list_like(index_like)
+            and len(index_like) > 0
+            and isinstance(index_like[0], tuple)
+        ):
+            try:
+                return pandas.MultiIndex.from_tuples(index_like)
+            except TypeError:
+                # not all tuples
+                pass
+        return ensure_index(index_like)
+
     def reindex(
         self,
         index=None,
@@ -2236,7 +2265,9 @@ def reindex(
         new_query_compiler = None
         if index is not None:
             if not isinstance(index, pandas.Index):
-                index = pandas.Index(index)
+                index = self._copy_index_metadata(
+                    source=self.index, destination=self._ensure_index(index, axis=0)
+                )
             if not index.equals(self.index):
                 new_query_compiler = self._query_compiler.reindex(
                     axis=0, labels=index, **kwargs
@@ -2246,7 +2277,9 @@ def reindex(
         final_query_compiler = None
         if columns is not None:
             if not isinstance(columns, pandas.Index):
-                columns = pandas.Index(columns)
+                columns = self._copy_index_metadata(
+                    source=self.columns, destination=self._ensure_index(columns, axis=1)
+                )
             if not columns.equals(self.columns):
                 final_query_compiler = new_query_compiler.reindex(
                     axis=1, labels=columns, **kwargs


Test patch:
diff --git a/modin/pandas/test/dataframe/test_indexing.py b/modin/pandas/test/dataframe/test_indexing.py
--- a/modin/pandas/test/dataframe/test_indexing.py
+++ b/modin/pandas/test/dataframe/test_indexing.py
@@ -671,6 +671,51 @@ def test_reindex():
     )
 
 
+def test_reindex_4438():
+    index = pd.date_range(end="1/1/2018", periods=3, freq="h", name="some meta")
+    new_index = list(reversed(index))
+
+    # index case
+    modin_df = pd.DataFrame([1, 2, 3], index=index)
+    pandas_df = pandas.DataFrame([1, 2, 3], index=index)
+    new_modin_df = modin_df.reindex(new_index)
+    new_pandas_df = pandas_df.reindex(new_index)
+    df_equals(new_modin_df, new_pandas_df)
+
+    # column case
+    modin_df = pd.DataFrame(np.array([[1], [2], [3]]).T, columns=index)
+    pandas_df = pandas.DataFrame(np.array([[1], [2], [3]]).T, columns=index)
+    new_modin_df = modin_df.reindex(columns=new_index)
+    new_pandas_df = pandas_df.reindex(columns=new_index)
+    df_equals(new_modin_df, new_pandas_df)
+
+    # multiindex case
+    multi_index = pandas.MultiIndex.from_arrays(
+        [("a", "b", "c"), ("a", "b", "c")], names=["first", "second"]
+    )
+    new_multi_index = list(reversed(multi_index))
+
+    modin_df = pd.DataFrame([1, 2, 3], index=multi_index)
+    pandas_df = pandas.DataFrame([1, 2, 3], index=multi_index)
+    new_modin_df = modin_df.reindex(new_multi_index)
+    new_pandas_df = pandas_df.reindex(new_multi_index)
+    df_equals(new_modin_df, new_pandas_df)
+
+    # multicolumn case
+    modin_df = pd.DataFrame(np.array([[1], [2], [3]]).T, columns=multi_index)
+    pandas_df = pandas.DataFrame(np.array([[1], [2], [3]]).T, columns=multi_index)
+    new_modin_df = modin_df.reindex(columns=new_multi_index)
+    new_pandas_df = pandas_df.reindex(columns=new_multi_index)
+    df_equals(new_modin_df, new_pandas_df)
+
+    # index + multiindex case
+    modin_df = pd.DataFrame([1, 2, 3], index=index)
+    pandas_df = pandas.DataFrame([1, 2, 3], index=index)
+    new_modin_df = modin_df.reindex(new_multi_index)
+    new_pandas_df = pandas_df.reindex(new_multi_index)
+    df_equals(new_modin_df, new_pandas_df)
+
+
 def test_reindex_like():
     df1 = pd.DataFrame(
         [