通过设置数量的分区按键对Spark Dataframe进行分组和分区。

时间:2018-11-15 05:33:43

标签: pyspark apache-spark-sql

我有一个带有多个标签的spark数据框,每个标签都具有对应的功能,如下所示:

+----------------+--------------------+
|           label|       feature_paths|
+----------------+--------------------+
|         person1|[-0.015756417, 0....|
|         person1|[-0.05177306, 0.1...|
|         person1|[-0.11631858, 0.1...|
|         person2|[-0.058303248, 0....|
|         person2|[-0.03415013, 0.0...|
+----------------+--------------------+

我想为每个标签(人)训练一个聚类模型,因此,基本上,我想为每个标签创建一个rdd,然后运行rdd.map(service)之类的映射操作,最终将保存一个{{1 }}每个实体的模型。

代码类似于:

gmm

我要实现的目标是:

  1. 创建一个rdd,其中分区数等于唯一标签数,例如:rdd.getNumPartition()= no_of_unique_labels。 每个rdd条目将具有多个功能,属于单个标签。

  2. 将每个rdd分区发送到服务功能。

直到现在我的实验:

  1. 执行def service(rddentry): label = rddentry[0] features = rddentry[1] print(label) from sklearn.mixture import BayesianGaussianMixture from sklearn.externals import joblib gmm = BayesianGaussianMixture(n_components=3, covariance_type="diag", init_params='kmeans') model = gmm.fit(features) joblib.dump(model, str(label)+'.joblib') return model 时,它将创建几个空的数据帧。

  2. sdf.repartition('label')也不起作用。它创建随机数量的分区。

我花了将近两天,但直到现在还没有具体结果。在正确方向上的任何帮助或指导都将有所帮助。

1 个答案:

答案 0 :(得分:1)

您可以将partitionBynew HashPartitioner(number_of_partitions)一起使用

要计算唯一标签数,还需要执行一项额外的操作,您可以将其用作所需分区的数量。

这里是示例,请注意:您需要成对的RDD才能执行此操作。因此,重新分区后,您可以map从元组中获取必要的时间

scala> val data = sc.parallelize(List("1","1","1","2","3","4","4","4"),4)
scala> data.glom.collect
res20: Array[Array[String]] = Array(Array(1, 1), Array(1, 2), Array(3, 4), Array(4, 4))
scala> val data_repart = data.keyBy(x=>x).partitionBy(new HashPartitioner(data.distinct.count.toInt))
scala> data_repart.glom.collect
res21: Array[Array[(String, String)]] = Array(Array((4,4), (4,4), (4,4)), Array((1,1), (1,1), (1,1)), Array((2,2)), Array((3,3)))
scala> data_repart.map(_._2).glom.collect
res22: Array[Array[String]] = Array(Array(4, 4, 4), Array(1, 1, 1), Array(2), Array(3))

让我知道是否有帮助。