Repository: modin-project/modin

Issue:
Calling Categorical on a DataFrame column with `ordered=True` results in numpy.AxisError
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: macOS Version 11.6
- **Modin version** (`modin.__version__`): Modin 0.13.2
- **Python version**: Python 3.8.11
- **Code we can use to reproduce**:

```
import modin.pandas as pd
from modin.pandas import Categorical
import pandas.api.types as pt
 
d = {'a': [1, 2, 3], 'b': [4, 5, 6]} 
df = pd.DataFrame(data=d)
df['a'] = Categorical(df['a'], ordered=True)
print(pt.is_categorical_dtype(df['a']))
```

### Describe the problem
When setting a column of a Modin DataFrame to a Categorical dtype version of that column with `ordered=True`, this results in a numpy.AxisError (see error traceback below). However, when the `ordered` argument is not set, Modin behaves as desired.

### Error Traceback
```
RayTaskError(AxisError): ray::deploy_ray_func() (pid=63501, ip=10.0.0.7)
  File "python/ray/_raylet.pyx", line 501, in ray._raylet.execute_task
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/ray/util/tracing/tracing_helper.py", line 330, in _function_with_tracing
    return function(*args, **kwargs)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/modin/core/execution/ray/implementations/pandas_on_ray/partitioning/virtual_partition.py", line 491, in deploy_ray_func
    result = func(*args)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/modin/core/dataframe/pandas/partitioning/axis_partition.py", line 160, in deploy_axis_func
    result = func(dataframe, **kwargs)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/modin/core/dataframe/pandas/dataframe/dataframe.py", line 1312, in _tree_reduce_func
    series_result = func(df, *args, **kwargs)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/modin/core/dataframe/pandas/dataframe/dataframe.py", line 1312, in _tree_reduce_func
    series_result = func(df, *args, **kwargs)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/modin/core/dataframe/pandas/dataframe/dataframe.py", line 276, in dtype_builder
    return df.apply(lambda col: find_common_type(col.values), axis=0)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/pandas/core/frame.py", line 8827, in apply
    return op.apply().__finalize__(self, method="apply")
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/pandas/core/apply.py", line 727, in apply
    return self.apply_standard()
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/pandas/core/apply.py", line 851, in apply_standard
    results, res_index = self.apply_series_generator()
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/pandas/core/apply.py", line 867, in apply_series_generator
    results[i] = self.f(v)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/modin/core/dataframe/pandas/dataframe/dataframe.py", line 276, in <lambda>
    return df.apply(lambda col: find_common_type(col.values), axis=0)
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/modin/core/storage_formats/pandas/parsers.py", line 127, in find_common_type_cat
    np.sort(np.unique([c for t in types for c in t.categories])[0]),
  File "<__array_function__ internals>", line 5, in sort
  File "/Users/naren/opt/anaconda3/envs/ponder/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 998, in sort
    a.sort(axis=axis, kind=kind, order=order)
numpy.AxisError: axis -1 is out of bounds for array of dimension 0
```



Discussion:

Resolving patch:
diff --git a/modin/core/storage_formats/pandas/parsers.py b/modin/core/storage_formats/pandas/parsers.py
--- a/modin/core/storage_formats/pandas/parsers.py
+++ b/modin/core/storage_formats/pandas/parsers.py
@@ -123,8 +123,15 @@ def find_common_type_cat(types):
     """
     if all(isinstance(t, pandas.CategoricalDtype) for t in types):
         if all(t.ordered for t in types):
+            categories = np.unique([c for t in types for c in t.categories])[0]
+            if categories.ndim != 0:
+                categories = np.sort(categories)
+            else:
+                # Cannot use np.sort() on array with ndim == 0
+                # tolist() is called on scalar value and returns an int
+                categories = [categories.tolist()]
             return pandas.CategoricalDtype(
-                np.sort(np.unique([c for t in types for c in t.categories])[0]),
+                categories,
                 ordered=True,
             )
         return union_categoricals(


Test patch:
diff --git a/modin/pandas/test/test_series.py b/modin/pandas/test/test_series.py
--- a/modin/pandas/test/test_series.py
+++ b/modin/pandas/test/test_series.py
@@ -2131,6 +2131,15 @@ def test_iloc_assigning_scalar_none_to_string_series():
     df_equals(modin_series, pandas_series)
 
 
+def test_set_ordered_categorical_column():
+    data = {"a": [1, 2, 3], "b": [4, 5, 6]}
+    mdf = pd.DataFrame(data)
+    pdf = pandas.DataFrame(data)
+    mdf["a"] = pd.Categorical(mdf["a"], ordered=True)
+    pdf["a"] = pandas.Categorical(pdf["a"], ordered=True)
+    df_equals(mdf, pdf)
+
+
 @pytest.mark.parametrize("data", test_data_values, ids=test_data_keys)
 def test_lt(data):
     modin_series, pandas_series = create_test_series(data)