Spark 从超级数据帧优化方法生成子数据帧
Posted
技术标签:
【中文标题】Spark 从超级数据帧优化方法生成子数据帧【英文标题】:Spark generate Sub Dataframes from a super Dataframe Optimized approach 【发布时间】:2017-09-19 09:43:14 【问题描述】:这是输入 Spark 数据帧。根据“代码类型”,我需要将此数据帧拆分为子数据帧,如下所示
val dsTotal = fr.toDF("Key","Code")
dsTotal.show()
--------------
|key | Code |
--------------
|200 | DS |
|300 | CP |
|400 | DS |
|76 | OR |
|45 | CP |
|34 | DS |
|33 | OR |
|200 | DS |
--------------
我在同一个超级数据帧上反复使用过滤器选项来创建子数据帧。有没有其他更好的方法来生成子数据帧
val ds1 = dsTotal.filter(col("Code").equalTo("CP"))
ds1.show()
--------------
|key | Code |
--------------
|45 | CP |
|300 | CP |
--------------
val ds2 = dsTotal.filter(col("Code").equalTo("DS"))
ds2.show()
--------------
|key | Code |
--------------
|200 | DS |
|400 | DS |
|200 | DS |
|34 | DS |
--------------
val ds3 = dsTotal.filter(col("Code").equalTo("OR"))
ds3.show()
--------------
|key | Code |
--------------
|76 | OR |
|33 | OR |
--------------
【问题讨论】:
接下来你打算用你的数据框做什么?如果只需要保存,请在 DataFrameWriter 上使用partitionBy
。详情请见***.com/questions/42645836/…。
我只想将数据帧拆分为子数据帧,以便在后续编码中使用这些子数据帧。
【参考方案1】:
filter
和select
是我见过的split
和dataframe
到subdataframe
s 的最佳方法之一。
所以你有最好的方法之一,但你的filter
有Code
的静态检查,可以通过执行以下操作来避免。
第一步是获取Code
列的distinct
值
import org.apache.spark.sql.functions._
val array = df.select(collect_list("Code")).first()(0).asInstanceOf[mutable.WrappedArray[String]].distinct
这应该给你
WrappedArray(DS, CP, OR)
下一步是遍历distinct
值并将subdataframe
s 存储在hashmap
中
val splittedDFs : mutable.HashMap[String, DataFrame] = mutable.HashMap.empty[String, DataFrame]
for(key <- array)
splittedDFs ++= mutable.HashMap(key -> df.filter($"Code" === key))
现在您可以访问子数据框了
splittedDFs("CP").show(false)
应该是
+---+----+
|key|Code|
+---+----+
|300|CP |
|45 |CP |
+---+----+
您也可以使用select
代替filter
。
希望回答对你有帮助
【讨论】:
以上是关于Spark 从超级数据帧优化方法生成子数据帧的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 spark.read.jdbc 读取不同 Pyspark 数据帧中的多个文件