spark scala中对分组数据中非键、非整数列上的数据进行排序的解决方案是什么? 按类别的产品价格对产品数据进行排序

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

我有一个产品的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)
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)中
    
  • 转换为数据帧,然后转换为groupBy product_category_id,但在groupBy之后,sortBy或orderBy不起作用
  • 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中对分组数据中非键、非整数列上的数据进行排序的解决方案是什么
  • 如何在scala中按升序和降序对两个不同的非键、非int列上的数据进行排序?(这与我面临的另一个问题有关)

  • 我是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)])]

  • 首先,您需要将映射用于iterable,然后才能对数据进行排序
  • 使用map获取数据作为元素,从map中获取元素(值)后,按照您想要的顺序对数据进行排序
  • 数据帧的步骤2

    在spark和sparksql中使用window函数实现了对有列数据和无聚合数据的排序。

    非常感谢您的回复,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)