Repository: dask/dask
File: dask/dataframe/partitionquantiles.py (Python)

Code before:
            vals, _ = _percentile(array_safe(data, like=data.values), qs, interpolation)
        except (TypeError, NotImplementedError):
            # `data.values` doesn't work for cudf, so we need to
            # use `quantile(..., method="table")` as a fallback
            interpolation = "nearest"
            vals = (
                data.to_frame()
                .quantile(
                    q=qs / 100,
                    interpolation=interpolation,
                    numeric_only=False,
                    method="table",
                )
                .iloc[:, 0]
            )

    if (
        is_cupy_type(data)
        and interpolation == "linear"
        and np.issubdtype(data.dtype, np.integer)
    ):
        vals = np.round(vals).astype(data.dtype)
        if qs[0] == 0:
            # Ensure the 0th quantile is the minimum value of the data
            vals[0] = data.min()
    vals_and_weights = percentiles_to_weights(qs, vals, length)
    return vals_and_weights


def dtype_info(df):
    info = None
    if isinstance(df.dtype, pd.CategoricalDtype):
        data = df.values
        info = (data.categories, data.ordered)
    return df.dtype, info


def partition_quantiles(df, npartitions, upsample=1.0, random_state=None):
    """Approximate quantiles of Series used for repartitioning"""
    assert isinstance(df, Series)
    # currently, only Series has quantile method
    # Index.quantile(list-like) must be pd.Series, not pd.Index
    return_type = Series

    qs = np.linspace(0, 1, npartitions + 1)
    token = tokenize(df, qs, upsample)
    if random_state is None:
        random_state = int(token, 16) % np.iinfo(np.int32).max
    state_data = random_state_data(df.npartitions, random_state)

    df_keys = df.__dask_keys__()

Review comment (suggestion):
My sense is that this entire code block can/should be removed for the sake of simplicity. However, I'm currently  leaving the `.values` operation in place to keep the scope if this PR small.

Code after:
        # Series.quantile doesn't work with some data types (e.g. strings)
        if PANDAS_GE_150:
            # Fall back to DataFrame.quantile with "nearest" interpolation
            interpolation = "nearest"
            vals = (
                data.to_frame()
                .quantile(
                    q=qs / 100,
                    interpolation=interpolation,
                    numeric_only=False,
                    method="table",
                )
                .iloc[:, 0]
            )
        else:
            # Fall back to ndarray (Not supported for cuDF)
            vals, _ = _percentile(array_safe(data, like=data.values), qs, interpolation)

    # Convert to array if necessary (and possible)
    if is_series_like(vals):
        try:
            vals = vals.values
        except (ValueError, TypeError):
            # cudf->cupy won't work if nulls are present,
            # or if this is a string dtype
            pass

    if (
        is_cupy_type(data)
        and interpolation == "linear"
        and np.issubdtype(data.dtype, np.integer)
    ):
        vals = np.round(vals).astype(data.dtype)
        if qs[0] == 0:
            # Ensure the 0th quantile is the minimum value of the data
            vals[0] = data.min()
    vals_and_weights = percentiles_to_weights(qs, vals, length)
    return vals_and_weights


def dtype_info(df):
    info = None
    if isinstance(df.dtype, pd.CategoricalDtype):
        data = df.values
        info = (data.categories, data.ordered)
    return df.dtype, info


def partition_quantiles(df, npartitions, upsample=1.0, random_state=None):
    """Approximate quantiles of Series used for repartitioning"""
    assert isinstance(df, Series)