code: def _rebin(self,xdx,rebin):
          
  
          x = xdx[0]
          dx = xdx[1]
          rebin = int(rebin)
          
          # easy end condition
          if rebin <= 1:
              return (x,dx)
          
          # Rebin Discard unused bins
          lenx = len(x)
          x_rebin = []
          dx_rebin = []
          
          # avoid dividing by zero
          dx[dx==0] = np.inf
          
          # weighted mean
          for i in np.arange(0,lenx,rebin):
              w = 1./dx[i:i+rebin-1]**2
              wsum = np.sum(w)
              
              if wsum == 0:
                  x_rebin.append(np.mean(x[i:i+rebin-1]))
                  dx_rebin.append(np.std(x[i:i+rebin-1]))
              else:
                  x_rebin.append(np.sum(x[i:i+rebin-1]*w)/wsum)
                  dx_rebin.append(1./wsum**0.5)
          return np.array([x_rebin,dx_rebin])
docs: Rebin array x with weights 1/dx**2 by factor rebin.
              
              Inputs: 
                  xdx = [x,dx]
                  rebin = int
              Returns [x,dx] after rebinning.