Apache spark 如何在PySpark中存储垃圾?

Apache spark 如何在PySpark中存储垃圾?,apache-spark,pyspark,Apache Spark,Pyspark,例如,我想根据年龄将一个DataFrame的人分为以下4个箱子 age_bins = [0, 6, 18, 60, np.Inf] age_labels = ['infant', 'minor', 'adult', 'senior'] 我将使用pandas.cut()在pandas中执行此操作。如何在PySpark中执行此操作?您可以使用spark中ml库中的Bucketizer功能转换 values = [("a", 23), ("b", 45), ("c", 10), ("d", 60),

例如,我想根据年龄将一个
DataFrame
的人分为以下4个箱子

age_bins = [0, 6, 18, 60, np.Inf]
age_labels = ['infant', 'minor', 'adult', 'senior']

我将使用
pandas.cut()
pandas
中执行此操作。如何在
PySpark
中执行此操作?

您可以使用spark中ml库中的Bucketizer功能转换

values = [("a", 23), ("b", 45), ("c", 10), ("d", 60), ("e", 56), ("f", 2), ("g", 25), ("h", 40), ("j", 33)]


df = spark.createDataFrame(values, ["name", "ages"])


from pyspark.ml.feature import Bucketizer
bucketizer = Bucketizer(splits=[ 0, 6, 18, 60, float('Inf') ],inputCol="ages", outputCol="buckets")
df_buck = bucketizer.setHandleInvalid("keep").transform(df)

df_buck.show()
输出

+----+----+-------+
|name|ages|buckets|
+----+----+-------+
|   a|  23|    2.0|
|   b|  45|    2.0|
|   c|  10|    1.0|
|   d|  60|    3.0|
|   e|  56|    2.0|
|   f|   2|    0.0|
|   g|  25|    2.0|
|   h|  40|    2.0|
|   j|  33|    2.0|
+----+----+-------+
如果需要每个bucket的名称,可以使用udf创建一个具有bucket名称的新列

from pyspark.sql.functions import udf
from pyspark.sql.types import *

t = {0.0:"infant", 1.0: "minor", 2.0:"adult", 3.0: "senior"}
udf_foo = udf(lambda x: t[x], StringType())
df_buck.withColumn("age_bucket", udf_foo("buckets")).show()
输出

+----+----+-------+----------+
|name|ages|buckets|age_bucket|
+----+----+-------+----------+
|   a|  23|    2.0|     adult|
|   b|  45|    2.0|     adult|
|   c|  10|    1.0|     minor|
|   d|  60|    3.0|    senior|
|   e|  56|    2.0|     adult|
|   f|   2|    0.0|    infant|
|   g|  25|    2.0|     adult|
|   h|  40|    2.0|     adult|
|   j|  33|    2.0|     adult|
+----+----+-------+----------+

您还可以编写PySpark UDF:

def categorizer(age):
  if age < 6:
    return "infant"
  elif age < 18:
    return "minor"
  elif age < 60:
    return "adult"
  else: 
    return "senior"

在我的例子中,我必须随机存储一个字符串值列,因此需要额外的步骤:

from pyspark.sql.types import LongType, IntegerType
import pyspark.sql.functions as F


buckets_number = 4    # number of buckets desired

df.withColumn("sub", F.substring(F.md5('my_col'), 0, 16)) \
  .withColumn("translate", F.translate("sub", "abcdefghijklmnopqrstuvwxyz", "01234567890123456789012345").cast(LongType())) \
  .select("my_col",
         (F.col("translate") % (buckets_number + 1)).cast(IntegerType()).alias("bucket_my_col"))
  • 用MD5散列它
  • 将结果子串为16个字符(否则在以下步骤中的数字会太大)
  • 用数字翻译MD5生成的字母
  • 根据所需桶数应用模函数
  • from pyspark.sql.types import LongType, IntegerType
    import pyspark.sql.functions as F
    
    
    buckets_number = 4    # number of buckets desired
    
    df.withColumn("sub", F.substring(F.md5('my_col'), 0, 16)) \
      .withColumn("translate", F.translate("sub", "abcdefghijklmnopqrstuvwxyz", "01234567890123456789012345").cast(LongType())) \
      .select("my_col",
             (F.col("translate") % (buckets_number + 1)).cast(IntegerType()).alias("bucket_my_col"))