spark scala中对分组数据中非键、非整数列上的数据进行排序的解决方案是什么? 按类别的产品价格对产品数据进行排序
我有一个产品的RDD列:(产品id、产品类别id、产品名称、产品描述、产品价格、产品图片)spark scala中对分组数据中非键、非整数列上的数据进行排序的解决方案是什么? 按类别的产品价格对产品数据进行排序,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我有一个产品的RDD列:(产品id、产品类别id、产品名称、产品描述、产品价格、产品图片) val prdMap=prd.map(r=>(r.split(“,”)(1).toInt,(r.split(“,”)(4),r.split(“,”)(0),r.split(“,”)(2))) prdMap.take(5.foreach)(打印项次) val groupByCategory=prdMap.groupByKey() groupByCategory.take(2).foreach(println
val prdMap=prd.map(r=>(r.split(“,”)(1).toInt,(r.split(“,”)(4),r.split(“,”)(0),r.split(“,”)(2)))
prdMap.take(5.foreach)(打印项次)
val groupByCategory=prdMap.groupByKey()
groupByCategory.take(2).foreach(println)
RDD元素按照Category_id正确分组,之后我必须根据scala中的product_price对数据进行排序
如果将产品价格保留为字符串,则排序不正确
groupByCategory.sortBy(u._2).take(2).foreach(println)
实际结果
(36,压缩缓冲区(
(12.99789,TaylorMade男式燃烧器有限公司高尔夫手套),
(24.99791,Hirzl女子信托手感高尔夫手套)
(13.99990,FootJoy男式StaCool高尔夫手套)
预期结果
(36,压缩缓冲区(
(12.99789,TaylorMade男式燃烧器有限公司高尔夫手套),
(13.99990,FootJoy男式StaCool高尔夫手套),
(24.99791,Hirzl女子信托手感高尔夫手套)
我已经尝试了几种方法——通过将product_price作为键来创建元组,并基于此进行排序
val prdMap2=prd.map(r=>(r.split(“,”)1.toInt,(r.split(“,”)4.toFloat,(r.split(“,”)(0),r.split(“,”)(2)))
val groupByCategory2=prdMap2.groupByKey()
prdMap2.groupByKey().sortBy(u._2).take(5).foreach(println)
prdMap2.groupByKey().keyBy(u._2).take(5).foreach(println)
keyBy和sortBy都给出了空字符串错误
19/08/11 19:51:29错误执行器。执行器:300.0阶段任务2.0中的异常(TID 553)
java.lang.NumberFormatException:空字符串
在sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1020)中
val-prdDF=prd.map(r=>(r.split(“,”)(1)、toInt、r.split(“,”)(4)、toFloat、r.split(“,”)(0)、r.split(“,”).toDF(“产品类别标识”、“产品价格”、“产品标识”、“产品名称”)
scala>prdDF.groupBy(“产品类别id”)
res294:org.apache.spark.sql.GroupedData=org.apache.spark.sql。GroupedData@45172e99
scala>prdDF.groupBy(“产品类别id”).sort(“产品价格”)
:43:错误:值排序不是org.apache.spark.sql.GroupedData的成员
scala>prdDF.groupBy(“产品类别id”).orderBy(“产品价格”)
:43:错误:值orderBy不是org.apache.spark.sql.GroupedData的成员
问题
我是spark scala的初学者,任何帮助都将不胜感激。您可以将
RDD[String]
输入转换为RDD[(K,V)]
,其中值
部分由用于排序的目标数字元素组成,如下所示:
val rdd = sc.parallelize(Seq(
("36,12.99,789,TaylorMade Men's Burner LTD Golf Glove"),
("36,24.99,791,Hirzl Women's Trust Feel Golf Glove"),
("36,13.99,790,FootJoy Men's StaCool Golf Glove")
))
import scala.util.{Try, Success, Failure}
val rdd2 = rdd.map{ line =>
val arr = line.split(",")
val a0 = Try(arr(0).toInt) match { case Success(i) => i; case Failure(_) => 0 }
val a1 = Try(arr(1).toDouble) match { case Success(d) => d; case Failure(_) => 0.0 }
(a0, (a1, arr.tail))
}
rdd2.groupByKey.mapValues( _.toList.sortBy(_._1).map(_._2) ).collect
// res1: Array[(Int, List[Array[String]])] = Array((36, List(
// Array(12.99, 789, TaylorMade Men's Burner LTD Golf Glove),
// Array(13.99, 790, FootJoy Men's StaCool Golf Glove),
// Array(24.99, 791, Hirzl Women's Trust Feel Golf Glove)
// )))
如果你在代码>星火2.4 +<代码>,考虑将<代码> RDD [(k,v)] /<代码>转换成<代码>数据文件< /代码>,并应用到<>代码> GROPBI/CopeTeCistBue/Cuff>聚合:
分组数组中。val df = rdd2.toDF("c1", "c2")
df.groupBy("c1").agg(array_sort(collect_list($"c2")).as("c2_sorted_list"))
您应该使用窗口函数对数据进行排序,因为您的数据是分布式的,并且您要排序的列可能不在同一个分区中,如果您使用orderBy,可能会产生错误的结果。 试着这样做:
val df = Seq((1,101,"xyz","ejflwkef",12.27,"image1"),(2,101,"xyz","ejflwkef",14.27,"image2"),(3,102,"xyz","ejflwkef",12.27,"image3")).toDF("product_id","product_category_id","product_name","product_description","product_price","product_image")
import org.apache.spark.sql.expressions.Window
val byCategoryId = Window.partitionBy("product_category_id").orderBy(desc("product_price"))
df.withColumn("rnk",row_number over byCategoryId).show()
RDD的步骤1
groupByCategory正在返回RDD[(Int,Iterable[(String,String,String)])]
非常感谢您的回复,Leo,我已经尝试在样本数据和源文件上使用第一种方法……在样本数据上,它工作正常,但是在源文件上,它的抛出错误val prdMap2=prd.map{r=>val arr=r.split(“,”)|(arr(1).toInt,(arr(4.toDouble,arr.tail))|prdMap2:org.apache.spark.rdd.rdd[(Int,(Double,Array[String])]]=scala>prdMap2.groupByKey.mapValues(.toList.sortBy(._1.map(._.u 2)).collect 19/08/15 01:49:00错误java.lang.NumberFormatException:empty StringSource文件格式…scala>prd.take(5.foreach(println)1,2,Quest Q64 10 FT.x 10 FT.斜腿瞬间U,,59.98,2,2,UnderArmour男式高光MC足球鞋,,129.99,3,2,UnderArmour男式叛徒D Mid Football Cl,,89.99,@Twinkle047,看起来您的一些数字字段包含无效或空值。我已经修改了答案以涵盖这些情况(默认为0,您可能需要相应地重置)。源中有1条错误记录,这就是它抛出错误的原因。删除错误记录后,它将给出wierd结果。输入-prdMap2.take(5)。foreach(println)(2,(59.98,1,任务Q64 10英尺x 10英尺斜腿瞬间U))(2,(129.99,2,Under Armour Men's Highlight MC足球鞋))(2,(89.99,3,Under Armour Men的Re Output-prdMap2.groupByKey.mapValues(.toList.sortBy(._1).map(._1.map(._2))。收集res338:Array[(Int,List[String])]=Array((52,List(11551161116116211631164116511661167116811691170117175117511751175117511761159158)),我在使用val-prdMap3=prd.filter(产品)时使用了这个函数val-prdMap2=prd.filter(产品=>product.split(“,”)(4)!=”).map{r=>val-arr=r.split(“,”)(arr(1).toInt,(arr(4).toDouble,arr(0),arr(2))}=
val prdMap = prd.map(r=> (r.split(",")(1).toInt,(r.split(",")(4),r.split(",")(0),r.split(",")(2) )))
prdMap.take(5).foreach(println)
val groupByCategory = prdMap.groupByKey()
groupByCategory.take(2).foreach(println)