【问题标题】:How to create Key-Value RDD (Scala)如何创建键值 RDD (Scala)
【发布时间】:2019-11-29 04:22:27
【问题描述】:

我有以下类型的 RDD(名称:AllTrainingDATA_RDD) org.apache.spark.rdd.RDD[(String, Double, Double, String)] :

(ICCH_1,4.3,3.0,Iris-setosa)
(ICCH_1,4.4,2.9,Iris-setosa)
(ICCH_1,4.4,3.0,Iris-setosa)
(ICCH_2,4.4,3.2,Iris-setosa)

第一列:ICCH_ID,第二列:X_Coordinates,第三列:Y_Coordinates,第四列:

我想最终得到一个 RDD,它有 第 2 列和第 3 列作为键第 4 列作为值。 ICCH_ID 列应保留在 RDD 中。

我目前基于一些互联网研究的尝试是这样的:

val AllTrainingDATA_RDD_Final = AllTrainingDATA_RDD.map(_.split(",")).keyBy(_(X_COORD,Y_COORD)).mapValues(fields => ("CLASS")).groupByKey().collect()

但是我得到了这个错误:

错误:值拆分不是 (String, Double, Double, String) 的成员

附:我正在使用 Databricks 社区版。我是 Scala 新手。

【问题讨论】:

  • 我建议您先学习一个简单的 Scala 教程。您的代码有很多简单的语法错误。我相信Tour of Scala 应该足够了。另外,请掌握两者的 ScaladocstdlibSpark。最后,谷歌是你的朋友。 - PS:错误对我来说很清楚,你的RDD是元组,元组没有拆分方法,你的字段访问也很糟糕。
  • 感谢您的建议。我完全同意你的看法!我会注意你指给我的教程!

标签: scala apache-spark key rdd


【解决方案1】:

让我们尝试逐步分解您的解决方案:

val AllTrainingDATA_RDD_Final = AllTrainingDATA_RDD
    .map(_.split(","))
    .keyBy(_(X_COORD,Y_COORD))
    .mapValues(fields => ("CLASS"))
    .groupByKey()
    .collect()

你的第一个问题是.map(_.split(","))的使用。这可能是在 RDD[String] 上完成的预处理阶段,以从文本输入行中提取逗号分隔值。但既然你已经这样做了,我们可以继续删除该部分。

你的第二个问题来自.keyBy(_(X_COORD,Y_COORD)),它看起来像这样:

错误:(String, Double, Double, String) 不带参数

这是因为您提供了 keyBy 一个匿名函数,该函数试图在 RDD 中的每个元组上应用 (X_COORD,Y_COORD),但您真正想要的是提取 x 和 y 坐标(第二和第三值)的函数从你的元组。实现此目的的一种方法是.keyBy{case (_, x, y, _) => (x, y)}

最后,您使用mapValues 只会为RDD 中的所有元素生成相同的字符串值("CLASS")。相反,您可以像这样简单地取元组中的第 4 个值:.mapValues(_._4)

将所有这些放在一起,您会得到以下代码:

val AllTrainingDATA_RDD_Final = AllTrainingDATA_RDD
    .keyBy{case (_, x, y, _) => (x, y)}
    .mapValues(_._4)
    .groupByKey()
    .collect()

由于您是 Scala 新手,我建议您在继续之前花一些时间熟悉语法、特性和 API。它将帮助您更快地理解和克服这些问题。

【讨论】:

  • 我非常感谢您完整而有用的回答。我知道你的最后一点是最重要的,我会注意你的建议。在此之前想到最后一个问题:当我打印您帮助我创建的 RDD 时,我意识到缺少列 ICCH_ID。我希望该专栏仍然存在。这可能吗?
  • @ArisKantas 它应该留在哪里?作为价值的一部分?
  • 作为最终 RDD 的一部分。是否可以将其作为价值的一部分?还是有办法让它分开?之后我需要根据该列进行一些计算,并且必须将这些信息提取到一个列表中。
  • @ArisKantas 它不能分开,它要么是键的一部分,要么是值的一部分。我会假设在价值是最好的选择。那么你只需要这个mapValues { case (id, _, _, class) => (id, class) }
  • 绝对完美!那行得通。事实上,它让我更好地理解了如何使用这些功能。非常感谢。
猜你喜欢
  • 2021-11-11
  • 2020-02-14
  • 2019-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 2018-03-24
相关资源
最近更新 更多