Repository: modin-project/modin

Issue:
BUG: `df.info` fails when columns get default (integer) names (KeyError)
### Modin version checks

- [X] I have checked that this issue has not already been reported.

- [X] I have confirmed this bug exists on the latest released version of Modin.

- [X] I have confirmed this bug exists on the main branch of Modin. (In order to do this you can follow [this guide](https://modin.readthedocs.io/en/stable/getting_started/installation.html#installing-from-the-github-master-branch).)


### Reproducible Example

```python
import modin.pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0, 100, (100, 100)))
df.info()
```


### Issue Description

When the column names are the default names (integers), we get a KeyError on column 0:
```python
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In [10], line 1
----> 1 df.info()

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/logging/logger_decorator.py:128, in enable_logging.<locals>.decorator.<locals>.run_and_log(*args, **kwargs)
    113 """
    114 Compute function with logging if Modin logging is enabled.
    115
   (...)
    125 Any
    126 """
    127 if LogMode.get() == "disable":
--> 128     return obj(*args, **kwargs)
    130 logger = get_logger()
    131 logger_level = getattr(logger, log_level)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/_compat/pandas_api/latest/dataframe.py:143, in LatestCompatibleDataFrame.info(self, verbose, buf, max_cols, memory_usage, show_counts, null_counts)
    134 def info(
    135     self,
    136     verbose: Optional[bool] = None,
   (...)
    141     null_counts: Optional[bool] = None,
    142 ):  # noqa: PR01, D200
--> 143     return self._info(
    144         verbose=verbose,
    145         buf=buf,
    146         max_cols=max_cols,
    147         memory_usage=memory_usage,
    148         show_counts=show_counts,
    149         null_counts=null_counts,
    150     )

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/logging/logger_decorator.py:128, in enable_logging.<locals>.decorator.<locals>.run_and_log(*args, **kwargs)
    113 """
    114 Compute function with logging if Modin logging is enabled.
    115
   (...)
    125 Any
    126 """
    127 if LogMode.get() == "disable":
--> 128     return obj(*args, **kwargs)
    130 logger = get_logger()
    131 logger_level = getattr(logger, log_level)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/pandas/dataframe.py:1144, in DataFrame._info(self, verbose, buf, max_cols, memory_usage, show_counts, null_counts)
   1141     output.append(columns._summary(name="Columns"))
   1143 if verbose:
-> 1144     verbose_repr(output)
   1145 else:
   1146     non_verbose_repr(output)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/pandas/dataframe.py:1133, in DataFrame._info.<locals>.verbose_repr(output)
   1129 to_append = put_str(" {}".format(i), lengths["head"]) + put_str(
   1130     col, lengths["column"]
   1131 )
   1132 if null_counts:
-> 1133     non_null = pprint_thing(non_null_count[col])
   1134     to_append += put_str(
   1135         "{} non-null".format(non_null), lengths["null"]
   1136     )
   1137 to_append += put_str(dtype, lengths["dtype"], spaces=0)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/pandas/core/series.py:982, in Series.__getitem__(self, key)
    979     return self._values[key]
    981 elif key_is_scalar:
--> 982     return self._get_value(key)
    984 if is_hashable(key):
    985     # Otherwise index.get_value will raise InvalidIndexError
    986     try:
    987         # For labels that don't resolve as scalars like tuples and frozensets

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/pandas/core/series.py:1092, in Series._get_value(self, label, takeable)
   1089     return self._values[label]
   1091 # Similar to Index.get_value, but we do not fall back to positional
-> 1092 loc = self.index.get_loc(label)
   1093 return self.index._get_values_for_loc(self, loc, label)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/pandas/core/indexes/range.py:396, in RangeIndex.get_loc(self, key, method, tolerance)
    394             raise KeyError(key) from err
    395     self._check_indexing_error(key)
--> 396     raise KeyError(key)
    397 return super().get_loc(key, method=method, tolerance=tolerance)

KeyError: '0'
```

### Expected Behavior

Should show the output of `df.info`

### Error Logs

<details>

```python-traceback

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In [10], line 1
----> 1 df.info()

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/logging/logger_decorator.py:128, in enable_logging.<locals>.decorator.<locals>.run_and_log(*args, **kwargs)
    113 """
    114 Compute function with logging if Modin logging is enabled.
    115
   (...)
    125 Any
    126 """
    127 if LogMode.get() == "disable":
--> 128     return obj(*args, **kwargs)
    130 logger = get_logger()
    131 logger_level = getattr(logger, log_level)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/_compat/pandas_api/latest/dataframe.py:143, in LatestCompatibleDataFrame.info(self, verbose, buf, max_cols, memory_usage, show_counts, null_counts)
    134 def info(
    135     self,
    136     verbose: Optional[bool] = None,
   (...)
    141     null_counts: Optional[bool] = None,
    142 ):  # noqa: PR01, D200
--> 143     return self._info(
    144         verbose=verbose,
    145         buf=buf,
    146         max_cols=max_cols,
    147         memory_usage=memory_usage,
    148         show_counts=show_counts,
    149         null_counts=null_counts,
    150     )

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/logging/logger_decorator.py:128, in enable_logging.<locals>.decorator.<locals>.run_and_log(*args, **kwargs)
    113 """
    114 Compute function with logging if Modin logging is enabled.
    115
   (...)
    125 Any
    126 """
    127 if LogMode.get() == "disable":
--> 128     return obj(*args, **kwargs)
    130 logger = get_logger()
    131 logger_level = getattr(logger, log_level)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/pandas/dataframe.py:1144, in DataFrame._info(self, verbose, buf, max_cols, memory_usage, show_counts, null_counts)
   1141     output.append(columns._summary(name="Columns"))
   1143 if verbose:
-> 1144     verbose_repr(output)
   1145 else:
   1146     non_verbose_repr(output)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/modin/pandas/dataframe.py:1133, in DataFrame._info.<locals>.verbose_repr(output)
   1129 to_append = put_str(" {}".format(i), lengths["head"]) + put_str(
   1130     col, lengths["column"]
   1131 )
   1132 if null_counts:
-> 1133     non_null = pprint_thing(non_null_count[col])
   1134     to_append += put_str(
   1135         "{} non-null".format(non_null), lengths["null"]
   1136     )
   1137 to_append += put_str(dtype, lengths["dtype"], spaces=0)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/pandas/core/series.py:982, in Series.__getitem__(self, key)
    979     return self._values[key]
    981 elif key_is_scalar:
--> 982     return self._get_value(key)
    984 if is_hashable(key):
    985     # Otherwise index.get_value will raise InvalidIndexError
    986     try:
    987         # For labels that don't resolve as scalars like tuples and frozensets

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/pandas/core/series.py:1092, in Series._get_value(self, label, takeable)
   1089     return self._values[label]
   1091 # Similar to Index.get_value, but we do not fall back to positional
-> 1092 loc = self.index.get_loc(label)
   1093 return self.index._get_values_for_loc(self, loc, label)

File ~/.miniconda3/envs/test/lib/python3.9/site-packages/pandas/core/indexes/range.py:396, in RangeIndex.get_loc(self, key, method, tolerance)
    394             raise KeyError(key) from err
    395     self._check_indexing_error(key)
--> 396     raise KeyError(key)
    397 return super().get_loc(key, method=method, tolerance=tolerance)

KeyError: '0'
```

</details>


### Installed Versions

<details>

modin: 0.16.1
pandas: 1.5.0
</details>



Discussion:

Resolving patch:
diff --git a/modin/pandas/dataframe.py b/modin/pandas/dataframe.py
--- a/modin/pandas/dataframe.py
+++ b/modin/pandas/dataframe.py
@@ -1144,10 +1144,10 @@ def verbose_repr(output):
             header, lengths = get_header()
             output.extend([columns_line, *header])
             for i, col in enumerate(columns):
-                i, col, dtype = map(pprint_thing, [i, col, dtypes[col]])
+                i, col_s, dtype = map(pprint_thing, [i, col, dtypes[col]])
 
                 to_append = put_str(" {}".format(i), lengths["head"]) + put_str(
-                    col, lengths["column"]
+                    col_s, lengths["column"]
                 )
                 if null_counts:
                     non_null = pprint_thing(non_null_count[col])


Test patch:
diff --git a/modin/pandas/test/dataframe/test_default.py b/modin/pandas/test/dataframe/test_default.py
--- a/modin/pandas/test/dataframe/test_default.py
+++ b/modin/pandas/test/dataframe/test_default.py
@@ -381,12 +381,15 @@ def test_info_default_param(data):
         assert modin_info[1:] == pandas_info[1:]
 
 
+# randint data covers https://github.com/modin-project/modin/issues/5137
+@pytest.mark.parametrize(
+    "data", [test_data_values[0], np.random.randint(0, 100, (10, 10))]
+)
 @pytest.mark.parametrize("verbose", [True, False])
 @pytest.mark.parametrize("max_cols", [10, 99999999])
 @pytest.mark.parametrize("memory_usage", [True, False, "deep"])
 @pytest.mark.parametrize("null_counts", [True, False])
-def test_info(verbose, max_cols, memory_usage, null_counts):
-    data = test_data_values[0]
+def test_info(data, verbose, max_cols, memory_usage, null_counts):
     with io.StringIO() as first, io.StringIO() as second:
         eval_general(
             pd.DataFrame(data),