code: def averageblocks(blks, imgsz, stpsz=None):
      
  
      blksz = blks.shape[:-1]
  
      if stpsz is None:
          stpsz = tuple(1 for _ in blksz)
  
  
      # Calculate the number of blocks that can fit in each dimension of
      # the images
      numblocks = tuple(int(np.floor((a-b)/c)+1) for a, b, c in
                        zip_longest(imgsz, blksz, stpsz, fillvalue=1))
  
      new_shape = blksz + numblocks
      blks = np.reshape(blks, new_shape)
  
      # Construct an imgs matrix of empty lists
      imgs = np.zeros(imgsz, dtype=blks.dtype)
      normalizer = np.zeros(imgsz, dtype=blks.dtype)
  
      # Iterate over each block and append the values to the corresponding
      # imgs cell
      for pos in np.ndindex(numblocks):
          slices = tuple(slice(a*c, a*c+b) for a, b, c in
                         zip(pos, blksz, stpsz))
          imgs[slices+pos[len(blksz):]] += blks[(Ellipsis, )+pos]
          normalizer[slices+pos[len(blksz):]] += blks.dtype.type(1)
  
      return np.where(normalizer > 0, (imgs/normalizer).astype(blks.dtype),
                      np.nan)
docs: Average blocks together from an ndarray to reconstruct ndarray signal.
  
      Parameters
      ----------
      blks : ndarray
        nd array of blocks of a signal
      imgsz : tuple
        tuple of the signal size
      stpsz : tuple, optional (default None, corresponds to steps of 1)
        tuple of step sizes between neighboring blocks
  
      Returns
      -------
      imgs : ndarray
        reconstructed signal, unknown pixels are returned as np.nan