繁体   English   中英

Apache Spark 将多行插入 DataFrame

[英]Apache Spark insert multiple rows into the DataFrame

首先,我绑定到Java 1.7Java Spark 1.6

我有很多列和数据,但让我们按照简单的示例进行操作。
所以假设我有一个简单的表(DataFrame)

+----+-------+
|  id|   name|
+----+-------+
|   1|      A|
+----+-------+
|   2|      B|
+----+-------+
|   3|      C|
+----+-------+

每次在每个单元格上,我都会调用自定义 udf function 进行所需的计算。 要求之一是每次在每行之后(或在具有某种值的每行之后)创建和 append 新的 N 行。

所以,就像:

+----+-------+
|  id|   name|
+----+-------+
|   1|      A| --> create 1 new Row (based on the udf calculations)
+----+-------+
|   2|      B| --> create 2 new Rows (based on the udf calculations)
+----+-------+
|   3|      C|
+----+-------+

预期结果是:

+----+-------+
|  id|   name|
+----+-------+
|   1|      A|
+----+-------+
|    |  (new)|
+----+-------+
|   2|      B|
+----+-------+
|    |  (new)|
+----+-------+
|    |  (new)|
+----+-------+
|   3|      C|
+----+-------+

我的误解-最好/正确的方法是什么?
我目前面临的问题:通过dataFrame.foreach(new Function1<Row, BoxedUnit>() {...}) <-- 不是功能接口; 没有java8; 必须实现整个接口; 代码结构复杂 - 总是收到Serializable error
就我个人而言,我不确定foreach是不是最好的方法,但我必须以某种方式迭代当前的 dataFrame。

此外,如果我做对了,我将始终应用unionAll来添加新行。
也许还有其他更好的方法可以通过Spark Sql或将其转换为RDD等来做到这一点。

回答我自己的问题(感谢@mck 提出的explode()想法)

所以,假设最初的 df 是:

DataFrame baseDf = ...

+----+-------+
|  id|   name|
+----+-------+
|   1|      A|
+----+-------+
|   2|      B|
+----+-------+

为 UDF 结果创建新的 'temp' 库并保存到新的单独 df 中:

DataFrame df1 = dataFrame.withColumn("temp")

+----+-------+-----+
|  id|   name| temp|
+----+-------+-----+
|   1|      A|     |
+----+-------+-----+
|   2|      B|     |
+----+-------+-----+

从 UDF 返回一个列表(或地图):

+----+-------+------+
|  id|   name|  temp|
+----+-------+------+
|   1|      A| [C,D]|
+----+-------+------+
|   2|      B| [E,F]|
+----+-------+------+

在 temp 列上应用explode()并将其移动到新的 dataframe:

DataFrame unfolded = df1.select(functions.col("id"), functions.explode(new Column("temp")).as("name"))

+----+-------+
|  id|   name|
+----+-------+
|   1|      C|
+----+-------+
|   1|      D|
+----+-------+
|   2|      E|
+----+-------+
|   2|      F|
+----+-------+

现在,由于unfoldedbaseDf的结构相同,我们可以应用unionAll ,然后根据需要进行排序或过滤:

baseDf = baseDf.unionAll(unfolded).sort("id", "name"):

+----+-------+
|  id|   name|
+----+-------+
|   1|      A|
+----+-------+
|   1|      C|
+----+-------+
|   1|      D|
+----+-------+
|   2|      B|
+----+-------+
|   2|      E|
+----+-------+
|   2|      F|
+----+-------+

添加了新字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM