code: def _test_percentile_between(self):
      quintiles = range(5)
      filter_names = ["pct_" + str(q) for q in quintiles]
      iter_quintiles = list(zip(filter_names, quintiles))
      terms = {
          name: self.f.percentile_between(q * 20.0, (q + 1) * 20.0)
          for name, q in iter_quintiles
      }
  
      # Test with 5 columns and no NaNs.
      eye5 = eye(5, dtype=float64)
      expected = {}
      for name, quintile in iter_quintiles:
          if quintile < 4:
              # There are four 0s and one 1 in each row, so the first 4
              # quintiles should be all the locations with zeros in the input
              # array.
              expected[name] = ~eye5.astype(bool)
          else:
              # The top quintile should match the sole 1 in each row.
              expected[name] = eye5.astype(bool)
  
      self.check_terms(
          terms=terms,
          expected=expected,
          initial_workspace={self.f: eye5},
          mask=self.build_mask(ones((5, 5))),
      )
  
      # Test with 6 columns, no NaNs, and one masked entry per day.
      eye6 = eye(6, dtype=float64)
      mask = array(
          [
              [1, 1, 1, 1, 1, 0],
              [0, 1, 1, 1, 1, 1],
              [1, 0, 1, 1, 1, 1],
              [1, 1, 0, 1, 1, 1],
              [1, 1, 1, 0, 1, 1],
              [1, 1, 1, 1, 0, 1],
          ],
          dtype=bool,
      )
      expected = {}
      for name, quintile in iter_quintiles:
          if quintile < 4:
              # Should keep all values that were 0 in the base data and were
              # 1 in the mask.
              expected[name] = mask & ~eye6.astype(bool)
          else:
              # The top quintile should match the sole 1 in each row.
              expected[name] = eye6.astype(bool)
  
      self.check_terms(
          terms=terms,
          expected=expected,
          initial_workspace={self.f: eye6},
          mask=self.build_mask(mask),
      )
  
      # Test with 6 columns, no mask, and one NaN per day.  Should have the
      # same outcome as if we had masked the NaNs.
      # In particular, the NaNs should never pass any filters.
      eye6_withnans = eye6.copy()
      putmask(eye6_withnans, ~mask, nan)
      expected = {}
      for name, quintile in iter_quintiles:
          if quintile < 4:
              # Should keep all values that were 0 in the base data and were
              # 1 in the mask.
              expected[name] = mask & (~eye6.astype(bool))
          else:
              # Should keep all the 1s in the base data.
              expected[name] = eye6.astype(bool)
  
      self.check_terms(
          terms,
          expected,
          initial_workspace={self.f: eye6},
          mask=self.build_mask(mask),
      )
  
imports: from functools import partial
  from itertools import product
  from operator import and_
  from toolz import compose
  from numpy import arange, argsort, array, eye, float64, full, inf, isfinite, nan, nanpercentile, ones, ones_like, putmask, rot90, sum
  from numpy.random import randn, seed
  import pandas
  from catalyst.errors import BadPercentileBounds
  from catalyst.pipeline import Filter, Factor, Pipeline
  from catalyst.pipeline.classifiers import Classifier
  from catalyst.pipeline.factors import CustomFactor
  from catalyst.pipeline.filters import All, Any, AtLeastN, StaticAssets, StaticSids
  from catalyst.testing import parameter_space, permute_rows, CatalystTestCase
  from catalyst.testing.fixtures import WithSeededRandomPipelineEngine
  from catalyst.testing.predicates import assert_equal
  from catalyst.utils.numpy_utils import float64_dtype, int64_dtype
  from .base import BasePipelineTestCase, with_default_shape
label_desc: Use image node_id 5 for calling the FilterTestCase obj's underlying member method code with example usage: obj._test_percentile_between() without return types