Construct a new factor that winsorizes the result of this factor.

        Winsorizing changes values ranked less than the minimum percentile to
        the value at the minimum percentile. Similarly, values ranking above
        the maximum percentile are changed to the value at the maximum
        percentile.

        Winsorizing is useful for limiting the impact of extreme data points
        without completely removing those points.

        If ``mask`` is supplied, ignore values where ``mask`` returns False
        when computing percentile cutoffs, and output NaN anywhere the mask is
        False.

        If ``groupby`` is supplied, winsorization is applied separately
        separately to each group defined by ``groupby``.

        Parameters
        ----------
        min_percentile: float, int
            Entries with values at or below this percentile will be replaced
            with the (len(input) * min_percentile)th lowest value. If low
            values should not be clipped, use 0.
        max_percentile: float, int
            Entries with values at or above this percentile will be replaced
            with the (len(input) * max_percentile)th lowest value. If high
            values should not be clipped, use 1.
        mask : zipline.pipeline.Filter, optional
            A Filter defining values to ignore when winsorizing.
        groupby : zipline.pipeline.Classifier, optional
            A classifier defining partitions over which to winsorize.

        Returns
        -------
        winsorized : zipline.pipeline.Factor
            A Factor producing a winsorized version of self.

        Examples
        --------
        .. code-block:: python

            price = USEquityPricing.close.latest
            columns={
                'PRICE': price,
                'WINSOR_1: price.winsorize(
                    min_percentile=0.25, max_percentile=0.75
                ),
                'WINSOR_2': price.winsorize(
                    min_percentile=0.50, max_percentile=1.0
                ),
                'WINSOR_3': price.winsorize(
                    min_percentile=0.0, max_percentile=0.5
                ),

            }

        Given a pipeline with columns, defined above, the result for a
        given day could look like:

        ::

                    'PRICE' 'WINSOR_1' 'WINSOR_2' 'WINSOR_3'
            Asset_1    1        2          4          3
            Asset_2    2        2          4          3
            Asset_3    3        3          4          3
            Asset_4    4        4          4          4
            Asset_5    5        5          5          4
            Asset_6    6        5          5          4

        See Also
        --------
        :func:`scipy.stats.mstats.winsorize`
        :meth:`pandas.DataFrame.groupby`

def winsorize(self,
                  min_percentile,
                  max_percentile,
                  mask=NotSpecified,
                  groupby=NotSpecified):
        """
        Construct a new factor that winsorizes the result of this factor.

        Winsorizing changes values ranked less than the minimum percentile to
        the value at the minimum percentile. Similarly, values ranking above
        the maximum percentile are changed to the value at the maximum
        percentile.

        Winsorizing is useful for limiting the impact of extreme data points
        without completely removing those points.

        If ``mask`` is supplied, ignore values where ``mask`` returns False
        when computing percentile cutoffs, and output NaN anywhere the mask is
        False.

        If ``groupby`` is supplied, winsorization is applied separately
        separately to each group defined by ``groupby``.

        Parameters
        ----------
        min_percentile: float, int
            Entries with values at or below this percentile will be replaced
            with the (len(input) * min_percentile)th lowest value. If low
            values should not be clipped, use 0.
        max_percentile: float, int
            Entries with values at or above this percentile will be replaced
            with the (len(input) * max_percentile)th lowest value. If high
            values should not be clipped, use 1.
        mask : zipline.pipeline.Filter, optional
            A Filter defining values to ignore when winsorizing.
        groupby : zipline.pipeline.Classifier, optional
            A classifier defining partitions over which to winsorize.

        Returns
        -------
        winsorized : zipline.pipeline.Factor
            A Factor producing a winsorized version of self.

        Examples
        --------
        .. code-block:: python

            price = USEquityPricing.close.latest
            columns={
                'PRICE': price,
                'WINSOR_1: price.winsorize(
                    min_percentile=0.25, max_percentile=0.75
                ),
                'WINSOR_2': price.winsorize(
                    min_percentile=0.50, max_percentile=1.0
                ),
                'WINSOR_3': price.winsorize(
                    min_percentile=0.0, max_percentile=0.5
                ),

            }

        Given a pipeline with columns, defined above, the result for a
        given day could look like:

        ::

                    'PRICE' 'WINSOR_1' 'WINSOR_2' 'WINSOR_3'
            Asset_1    1        2          4          3
            Asset_2    2        2          4          3
            Asset_3    3        3          4          3
            Asset_4    4        4          4          4
            Asset_5    5        5          5          4
            Asset_6    6        5          5          4

        See Also
        --------
        :func:`scipy.stats.mstats.winsorize`
        :meth:`pandas.DataFrame.groupby`
        """
        if not 0.0 <= min_percentile < max_percentile <= 1.0:
            raise BadPercentileBounds(
                min_percentile=min_percentile,
                max_percentile=max_percentile,
                upper_bound=1.0,
            )
        return GroupedRowTransform(
            transform=winsorize,
            transform_args=(min_percentile, max_percentile),
            factor=self,
            groupby=groupby,
            dtype=self.dtype,
            missing_value=self.missing_value,
            mask=mask,
            window_safe=self.window_safe,
        )