<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def change_numbering(self, new_index=None):
 """Change numbering to a new index. Changes the numbering of index and all dependent numbering The user has to make sure that the new_index consists of distinct elements. Args: new_index (list):
 If None the new_index is taken from 1 to the number of atoms. Returns: Zmat: Reindexed version of the zmatrix. """

        if (new_index is None):
            new_index = range(len(self))
        elif len(new_index) != len(self):
            raise ValueError('len(new_index) has to be the same as len(self)')

        c_table = self.loc[:, ['b', 'a', 'd']]
        # Strange bug in pandas where .replace is transitive for object columns
        # and non-transitive for all other types.
        # (Remember that string columns are just object columns)
        # Example:
        # A = {1: 2, 2: 3}
        # Transtitive [1].replace(A) gives [3]
        # Non-Transtitive [1].replace(A) gives [2]
        # https://github.com/pandas-dev/pandas/issues/5338
        # https://github.com/pandas-dev/pandas/issues/16051
        # https://github.com/pandas-dev/pandas/issues/5541
        # For this reason convert to int and replace then.

        c_table = c_table.replace(constants.int_label)
        try:
            c_table = c_table.astype('i8')
        except ValueError:
            raise ValueError('Due to a bug in pandas it is necessary to have '
                             'integer columns')
        c_table = c_table.replace(self.index, new_index)
        c_table = c_table.replace(
            {v: k for k, v in constants.int_label.items()})

        out = self.copy()
        out.unsafe_loc[:, ['b', 'a', 'd']] = c_table
        out._frame.index = new_index
        return out