<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _prepare_by_column_dtype(self, X):
 """Get distance functions for each column's dtype"""

        if not isinstance(X, pandas.DataFrame):
            raise TypeError('X must be a pandas DataFrame')

        numeric_columns = []
        nominal_columns = []
        numeric_ranges = []

        fit_data = numpy.empty_like(X)

        for i, dt in enumerate(X.dtypes):
            col = X.iloc[:, i]
            if is_categorical_dtype(dt):
                if col.cat.ordered:
                    numeric_ranges.append(col.cat.codes.max() - col.cat.codes.min())
                    numeric_columns.append(i)
                else:
                    nominal_columns.append(i)

                col = col.cat.codes
            elif is_numeric_dtype(dt):
                numeric_ranges.append(col.max() - col.min())
                numeric_columns.append(i)
            else:
                raise TypeError('unsupported dtype: %r' % dt)

            fit_data[:, i] = col.values

        self._numeric_columns = numpy.asarray(numeric_columns)
        self._nominal_columns = numpy.asarray(nominal_columns)
        self._numeric_ranges = numpy.asarray(numeric_ranges, dtype=float)
        self.X_fit_ = fit_data