当前位置: 首页 > 知识库问答 >
问题:

如何使用类型化数据集将多值列拆分为单独的行?

司知
2023-03-14

我面临着如何将多值列(即< code>List[String])拆分成单独的行的问题。

初始数据集有以下类型:数据集[(Integer,String,Double,scala.List[String])]

+---+--------------------+-------+--------------------+
| id|       text         | value |    properties      |
+---+--------------------+-------+--------------------+
|  0|Lorem ipsum dolor...|    1.0|[prp1, prp2, prp3..]|
|  1|Lorem ipsum dolor...|    2.0|[prp4, prp5, prp6..]|
|  2|Lorem ipsum dolor...|    3.0|[prp7, prp8, prp9..]|

生成的数据集应具有以下类型:

Dataset[(Integer, String, Double, String)]

并且应拆分属性,以便:

+---+--------------------+-------+--------------------+
| id|       text         | value |    property        |
+---+--------------------+-------+--------------------+
|  0|Lorem ipsum dolor...|    1.0|        prp1        |
|  0|Lorem ipsum dolor...|    1.0|        prp2        |
|  0|Lorem ipsum dolor...|    1.0|        prp3        |
|  1|Lorem ipsum dolor...|    2.0|        prp4        |
|  1|Lorem ipsum dolor...|    2.0|        prp5        |
|  1|Lorem ipsum dolor...|    2.0|        prp6        |

共有3个答案

闾丘高峰
2023-03-14

有一种方法可以做到:

val myRDD = sc.parallelize(Array(
  (0, "text0", 1.0, List("prp1", "prp2", "prp3")),
  (1, "text1", 2.0, List("prp4", "prp5", "prp6")),
  (2, "text2", 3.0, List("prp7", "prp8", "prp9"))
)).map{
  case (i, t, v, ps) => ((i, t, v), ps)
}.flatMapValues(x => x).map{
  case ((i, t, v), p) => (i, t, v, p)
}
何琨
2023-03-14

您可以使用< code>explode:

df.withColumn("property", explode($"property"))

示例:

val df = Seq((1, List("a", "b"))).toDF("A", "B")   
// df: org.apache.spark.sql.DataFrame = [A: int, B: array<string>]

df.withColumn("B", explode($"B")).show
+---+---+
|  A|  B|
+---+---+
|  1|  a|
|  1|  b|
+---+---+
景景胜
2023-03-14

通常建议使用< code>explode,但它来自非类型化的DataFrame API,如果您使用Dataset,我认为< code>flatMap操作符可能更合适(参见org.apache.spark.sql.Dataset)。

flatMap[U](func: (T) ⇒ TraversableOnce[U])(implicit arg0: Encoder[U]): Dataset[U]

(特定于斯卡拉)通过首先将函数应用于此数据集的所有元素,然后平展结果来返回新数据集。

您可以按如下方式使用它:

val ds = Seq(
  (0, "Lorem ipsum dolor", 1.0, Array("prp1", "prp2", "prp3")))
  .toDF("id", "text", "value", "properties")
  .as[(Integer, String, Double, scala.List[String])]

scala> ds.flatMap { t => 
  t._4.map { prp => 
    (t._1, t._2, t._3, prp) }}.show
+---+-----------------+---+----+
| _1|               _2| _3|  _4|
+---+-----------------+---+----+
|  0|Lorem ipsum dolor|1.0|prp1|
|  0|Lorem ipsum dolor|1.0|prp2|
|  0|Lorem ipsum dolor|1.0|prp3|
+---+-----------------+---+----+

// or just using for-comprehension
for {
  t <- ds
  prp <- t._4
} yield (t._1, t._2, t._3, prp)
 类似资料:
  • $title=$\请求['test\u bestellte\u title'] $anzahl=$_请求['test_bestellte_anzahl'] $groesse=$\u请求['test\u bestellette\u groesse']; 我想将这个值数组插入到sql表中,比如 但我不知道如何像上面所示插入它 到目前为止,我把他们分开了,这就是我被困的地方 提前感谢!

  • 问题内容: 我想将我的int值拆分为数字。例如,如果没有。是542,结果应为5,4,2。 我有2个选择。1)将int转换为String,然后使用getCharArray(),我可以使用单独的字符,然后将它们转换回int值。 2)将int转换为String,而不将其转换为char数组,对其进行迭代并获取所有数字。 还有其他解决方法。如果没有,哪个选项会很快? 问题答案:

  • 我有一个数据帧: 如何拆分该列,使每个值都在自己的列中? 我找到的唯一答案是关于将一列拆分成两列。如何将一列拆分成两列?

  • 我在presto上有一个表,它有多个记录的记录。在该记录中,我使用了这个简单的SQL查询,

  • 问题内容: 我的问题是我有一个这样的表: c1 | c2 | c3 | c4是一个由|分隔的值。 我的最终结果应如下所示: 我该怎么做呢? 谢谢 问题答案: 这就是您可以执行的操作,使用管道将字符串拆分并使用spark函数爆炸数据 输出: 希望这可以帮助!

  • 问题内容: 使用MySQL查询,如何像示例A那样获取表: 并创建一个类似于示例B的视图? 问题答案: 您可以简单地使用函数: 看到这个SQLFiddle 如果您的 班级 数目未知,请尝试此动态查询 输出: 看到这个SQLFiddle

  • 问题内容: 我的问题是我在列表中有值。我想将这些值分开并作为单独的参数发送。 我的代码是: 这行代码 不起作用,但是我想知道是否可以调用一些内置函数来将值从列表中分离出来,因此以后我们可以将它们作为两个不同的参数发送。与相似,但是要动态完成,因此我不必显式键入列表参数。 问题答案: 调用函数时,可以使用 args(参数)和* kwargs(用于关键字参数)。看一下这个博客,了解如何正确使用它。

  • 我有一个导航菜单,它使用WordPress'函数,首先在下拉子菜单中将父类别和所有子类别呈现到该类别。标记如下所示: 我希望能够将子类别分成列(每列有5或6个链接),但不知道如何去完成这件事。我已经花了近30个小时在这一点现在没有任何作用,所以任何想法将是非常感谢。提前道谢!