//  [python]
def rebin(self, nshells):
        """
        Rebins the data to nshells. Uses the scipy.stats.binned_statistic
        to bin the data. The standard deviation of each bin can be obtained
        by passing the statistics="std" keyword.

        Parameters
        ----------
        nshells : int
            Number of bins of new data.

        Returns
        -------
        self : Profile object

        """

        self.vel_prof_p, bins_p, bin_edges_p = stats.binned_statistic(
            self.pos_prof_p,
            self.vel_prof_p * self.mass_prof_p,
            statistic="mean",
            bins=nshells,
        )
        self.vel_prof_p /= stats.binned_statistic(
            self.pos_prof_p,
            self.mass_prof_p,
            statistic="mean",
            bins=nshells,
        )[0]
        self.vel_prof_n, bins_n, bin_edges_n = stats.binned_statistic(
            self.pos_prof_n,
            self.vel_prof_n * self.mass_prof_n,
            statistic="mean",
            bins=nshells,
        )
        self.vel_prof_n /= stats.binned_statistic(
            self.pos_prof_n,
            self.mass_prof_n,
            statistic="mean",
            bins=nshells,
        )[0]

        for spec in self.species:
            self.xnuc_prof_p[spec] = (
                stats.binned_statistic(
                    self.pos_prof_p,
                    self.xnuc_prof_p[spec] * self.mass_prof_p,
                    statistic="mean",
                    bins=nshells,
                )[0]
                / stats.binned_statistic(
                    self.pos_prof_p,
                    self.mass_prof_p,
                    statistic="mean",
                    bins=nshells,
                )[0]
            )
            self.xnuc_prof_n[spec] = (
                stats.binned_statistic(
                    self.pos_prof_n,
                    self.xnuc_prof_n[spec] * self.mass_prof_n,
                    statistic="mean",
                    bins=nshells,
                )[0]
                / stats.binned_statistic(
                    self.pos_prof_n,
                    self.mass_prof_n,
                    statistic="mean",
                    bins=nshells,
                )[0]
            )

        self.vol_prof_p = np.array(
            [
                4 / 3 * np.pi * (bin_edges_p[i + 1] ** 3 - bin_edges_p[i] ** 3)
                for i in range(len(bin_edges_p) - 1)
            ]
        )
        self.vol_prof_n = np.array(
            [
                4 / 3 * np.pi * (bin_edges_n[i + 1] ** 3 - bin_edges_n[i] ** 3)
                for i in range(len(bin_edges_n) - 1)
            ]
        )

        self.mass_prof_p = stats.binned_statistic(
            self.pos_prof_p,
            self.mass_prof_p,
            statistic="sum",
            bins=nshells,
        )[0]
        self.mass_prof_n = stats.binned_statistic(
            self.pos_prof_n,
            self.mass_prof_n,
            statistic="sum",
            bins=nshells,
        )[0]

        self.rho_prof_p = self.mass_prof_p / self.vol_prof_p
        self.rho_prof_n = self.mass_prof_n / self.vol_prof_n

        self.pos_prof_p = np.array(
            [(bin_edges_p[i] + bin_edges_p[i + 1]) / 2 for i in range(len(bin_edges_p) - 1)]
        )
        self.pos_prof_n = np.array(
            [(bin_edges_n[i] + bin_edges_n[i + 1]) / 2 for i in range(len(bin_edges_n) - 1)]
        )

        return self