pandas数据分割pd.cut使用总结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pandas数据分割pd.cut使用总结相关的知识,希望对你有一定的参考价值。

参考技术A pandas.cut用来把一组数据分割成离散的区间。比如有一组年龄数据,可以使用pandas.cut将年龄数据分割成不同的年龄段并打上标签。

参数含义

x: 被切分的类数组(array-like)数据,必须是1维的(不能用DataFrame);

bins :bins是被切割后的区间(或者叫“桶”、“箱”、“面元”),有3中形式:一个int型的标量、标量序列(数组)或者pandas.IntervalIndex 。

一个int型的标量——当bins为一个int型的标量时,代表将x平分成bins份。x的范围在每侧扩展0.1%,以包括x的最大值和最小值。

标量序列 —— 标量序列定义了被分割后每一个bin的区间边缘,此时x没有扩展。

pandas.IntervalIndex ——定义要使用的精确区间。

right :bool型参数,默认为True,表示是否包含区间右部。比如如果bins=[1,2,3],right=True,则区间为(1,2],(2,3];right=False,则区间为(1,2),(2,3)。

labels :给分割后的bins打标签,比如把年龄x分割成年龄段bins后,可以给年龄段打上诸如青年、中年的标签。labels的长度必须和划分后的区间长度相等,比如bins=[1,2,3],划分后有2个区间(1,2],(2,3],则labels的长度必须为2。如果指定labels=False,则返回x中的数据在第几个bin中(从0开始)。

retbins :bool型的参数,表示是否将分割后的bins返回,当bins为一个int型的标量时比较有用,这样可以得到划分后的区间,默认为False。

precision :保留区间小数点的位数,默认为3.

include_lowest :bool型的参数,表示区间的左边是开还是闭的,默认为false,也就是不包含区间左部(闭)。

duplicates :是否允许重复区间。有两种选择:raise:不允许,drop:允许。

out :一个pandas.Categorical, Series或者ndarray类型的值,代表分区后x中的每个值在哪个bin(区间)中,如果指定了labels,则返回对应的label。

bins :分隔后的区间,当指定retbins为True时返回。

🌰:这里拿给年龄分组当做例子。

参考: pandas.cut使用总结 - ColdCode - 博客园

有没有办法在 sklearn 管道中链接 pd.cut FunctionTransformer?

【中文标题】有没有办法在 sklearn 管道中链接 pd.cut FunctionTransformer?【英文标题】:Is there a way to chain a pd.cut FunctionTransformer in a sklearn Pipeline? 【发布时间】:2020-10-07 22:23:07 【问题描述】:

我正在使用 sklearn 制作 DataFrame 预处理管道并链接各种类型的预处理步骤。

我想链接 SimpleImputer 变压器和 FunctionTransformer 应用 pd.qcut(或 pd.cut),但我不断收到以下错误:

ValueError: 输入数组必须是一维的

这是我的代码:

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import FunctionTransformer

class FeatureSelector(BaseEstimator, TransformerMixin):
    def __init__(self, features):
        self._features = features

    def fit(self, X, y=None):
        return self

    def transform(self, X, y=None):
        return X[self._features]

fare_transformer = Pipeline([
    ('fare_selector', FeatureSelector(['Fare'])),
    ('fare_imputer', SimpleImputer(strategy='median')),
    ('fare_bands', FunctionTransformer(func=pd.qcut, kw_args='q': 5))
])

如果我简单地将FeatureSelector 转换器和FunctionTransformerpd.qcut 链接并省略SimpleImputer,也会发生同样的情况:

fare_transformer = Pipeline([
    ('fare_selector', FeatureSelector(['Fare'])),
    ('fare_bands', FunctionTransformer(func=pd.qcut, kw_args='q': 5))
])

我广泛搜索了 *** 和 google,但找不到解决此问题的方法。在这里的任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

sklearn 已经有这样的转换器,KBinsDiscretizer(匹配pd.qcut,使用strategy='quantile')。它的主要区别在于transforms 测试数据的方式:FunctionTransformer 版本将“重新调整”分位数,而内置的KBinsDiscretizer 将保存分位数统计信息以对测试数据进行分箱。正如@m_power 在评论中指出的那样,它们在 bin 边缘附近以及转换后数据的格式也有所不同。

但要具体解决该错误:这意味着您的函数 qcut 仅适用于一维数组,而 FunctionTransformer 发送整个数据帧。您可以在 qcut 周围定义一个薄包装器来完成这项工作,例如

def frame_qcut(X, y=None, q=10):
    return X.apply(pd.qcut, axis=0, q=q)

(假设您将获得一个数据框。)

【讨论】:

感谢您的及时回复。通过使用 FeatureSelector 从我的 DataFrame 中选择“Fare”列,我以为我正在为 FunctionTransformer 提供一个应该与 pd.qcut 一起使用的熊猫系列,例如pd.qcut(df['Fare'], q=5) @LazyEval 在管道中的FeatureSelector 参数中将['Fare'] 替换为'Fare' 将以这种方式工作:X[['Fare']] 是一个数据框,但X['Fare'] 是一个系列,这将在qcut 工作。这适用于您的第二个更简单的管道,但会在第一个中失败,因为现在 SimpleImputer 将抱怨一维输入。 哦,好吧,我什至没有真正想过 X['Fare'] 和 X[['Fare']] 之间的区别......我傻了。谢谢! 当应用于一个简单的一维数组(例如np.random.rand(10,1))时,quantile KBinsDiscretizerpd.qcut 没有得到相同的结果。根据您的说法,两种解决方案应该是相同的。 @m_power,数学内容是一样的(虽然我可以理解由于插值造成的细微差异,但我在你这样的随机示例中没有发现任何差异),只是格式不同。 KBinsDiscretizerbin_edges_ 匹配 qcut 的第二个可选输出 bins 随机示例。 qcut 将输出作为间隔返回,而KBinsDiscretizer 将编码返回为 one-hot 或 ordinal。

以上是关于pandas数据分割pd.cut使用总结的主要内容,如果未能解决你的问题,请参考以下文章

pandas.cut使用总结

pandas-08 pd.cut()的功能和作用

PySpark 中 pandas.cut() 的等价物是啥?

pandas中两个dataframe怎么比较

Pandas 数据框中的分类变量?

Pandas总结第五节 Pandas 数据查询方法总结_df.loc()总结