【问题标题】:What is the equivalent of pandas.cut() in PySpark?PySpark 中 pandas.cut() 的等价物是什么?
【发布时间】:2021-05-06 14:02:10
【问题描述】:

pandas.cut() 用于将值分箱为离散区间。例如,

pd.cut(
    np.array([0.2, 0.25, 0.36, 0.55, 0.67, 0.78]), 
    3, 
    include_lowest=True, 
    right=False
)

Out[9]: 
[[0.2, 0.393), [0.2, 0.393), [0.2, 0.393), [0.393, 0.587), [0.587, 0.781), [0.587, 0.781)]
Categories (3, interval[float64]): [[0.2, 0.393) < [0.393, 0.587) < [0.587, 0.781)]

如何在 PySpark 中实现同样的效果?我查看了QuantileDiscretizer,但它绝对不等同于pd.cut(),因为它不返回间隔。

【问题讨论】:

    标签: python pandas apache-spark pyspark


    【解决方案1】:

    RDD.histogram 是 Spark 中类似的函数。

    假设数据包含在具有col1 列的数据框中。

    +----+
    |col1|
    +----+
    | 0.2|
    |0.25|
    |0.36|
    |0.55|
    |0.67|
    |0.78|
    +----+
    
    h = df.rdd.flatMap(lambda x: x).histogram(3) #change 3 to the number of expected intervals
    
    bins = [ (x, h[0][i+1]) for i,x in enumerate(h[0][:-1])]
    
    def label(bin):
        return f"'{bin[0]:5.2f} - {bin[1]:5.2f}'"
    
    e = "case "
    for bin in bins[:-1]:
        e += f"when col1 >= {bin[0]} and col1 < {bin[1]} then {label(bin)} "
    e += f"else {label(bins[-1])} end as bin"
    
    df.selectExpr("col1", e).show()
    

    输出:

    +----+-------------+
    |col1|          bin|
    +----+-------------+
    | 0.2| 0.20 -  0.39|
    |0.25| 0.20 -  0.39|
    |0.36| 0.20 -  0.39|
    |0.55| 0.39 -  0.59|
    |0.67| 0.59 -  0.78|
    |0.78| 0.59 -  0.78|
    +----+-------------+
    

    bins 包含作为元组的区间:

    [(0.2, 0.39333333333333337),
     (0.39333333333333337, 0.5866666666666667),
     (0.5866666666666667, 0.78)]
    

    【讨论】:

    • 这是否意味着如果我已经知道桶/间隔,我可以跳过直方图然后做CASE WHEN...
    • @Tokyo 是的,你是对的。当您知道间隔时,您可以简单地使用 for 循环
    • 这是否意味着,在每个 bin 中,项目的数量将相同?
    • @pnv 否,所有 bin 都覆盖了输入数据的最小值和最大值之间的相同区间,因此具有相同的长度 (0.1933..)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 2014-06-12
    • 1970-01-01
    • 2022-11-28
    • 2021-06-19
    • 2012-07-20
    相关资源
    最近更新 更多