class_docstr: Gap handling based on the median diff of the x_agg array.
class_docstr_tok: ["Gap","handling","based","on","the","median","diff","of","the","x_agg","array","."]
docstr: Calculate the median diff of the x_agg array.
  
  As median is more robust to outliers than the mean, the median is used to define
  the gap threshold.
  
  This method performs a divide and conquer heuristic to calculate the median;
  1. divide the array into `n_blocks` blocks (with `n_blocks` = 128)
  2. calculate the mean of each block
  3. calculate the median of the means
  => This proves to be a good approximation of the median of the full array, while
        being much faster than calculating the median of the full array.
docstr_tok: ["Calculate","the","median","diff","of","the","x_agg","array",".","As","median","is","more","robust","to","outliers","than","the","mean",",","the","median","is","used","to","define","the","gap","threshold",".","This","method","performs","a","divide","and","conquer","heuristic","to","calculate","the","median",";","1.","divide","the","array","into","`","n_blocks","`","blocks","(","with","`","n_blocks","`","=","128",")","2.","calculate","the","mean","of","each","block","3.","calculate","the","median","of","the","means","=",">","This","proves","to","be","a","good","approximation","of","the","median","of","the","full","array",",","while","being","much","faster","than","calculating","the","median","of","the","full","array","."]
code: def _calc_med_diff(
      self, x_agg: np.ndarray
  ) -> Tuple[float, np.ndarray]:
      """Calculate the median diff of the x_agg array.
  
      As median is more robust to outliers than the mean, the median is used to define
      the gap threshold.
  
      This method performs a divide and conquer heuristic to calculate the median;
      1. divide the array into `n_blocks` blocks (with `n_blocks` = 128)
      2. calculate the mean of each block
      3. calculate the median of the means
      => This proves to be a good approximation of the median of the full array, while
            being much faster than calculating the median of the full array.
      """
      # remark: thanks to the prepend -> x_diff.shape === len(s)
      x_diff = np.diff(x_agg, prepend=x_agg[0])
  
      # To do so - use an approach where we reshape the data
      # into `n_blocks` blocks and calculate the mean and then the median on that
      # Why use `median` instead of a global mean?
      #   => when you have large gaps, they will be represented by a large diff
      #      which will skew the mean way more than the median!
      n_blocks = 128
      if x_agg.shape[0] > 5 * n_blocks:
          blck_size = x_diff.shape[0] // n_blocks
  
          # convert the index series index diff into a reshaped view (i.e., sid_v)
          sid_v: np.ndarray = x_diff[: blck_size * n_blocks].reshape(
              n_blocks, -1
          )
  
          # calculate the mean fore each block and then the median of those means
          med_diff = np.median(np.mean(sid_v, axis=1))
      else:
          med_diff = np.median(x_diff)
  
      return med_diff, x_diff
  
file_path: plotly-resampler/plotly_resampler/aggregation/gap_handlers.py
imports: from __future__ import annotations
  from typing import Optional, Tuple
  import numpy
  from plotly_resampler.aggregation.gap_handler_interface import AbstractGapHandler
label_desc: Use image node_id 1 for calling the MedDiffGapHandler obj's underlying member method code with example usage: obj._calc_med_diff(x_agg) and returns: med_diff,  x_diff