我是Scala / spark的新手。我正在研究Scala / Spark应用程序,它从蜂巢表中选择几列,然后将其转换为Mutable映射,第一列是键,第二列是值。例如:
+--------+--+
| c1 |c2|
+--------+--+
|Newyork |1 |
| LA |0 |
|Chicago |1 |
+--------+--+
将转换为Scala.mutable.Map(Newyork -> 1, LA -> 0, Chicago -> 1)
以下是我上述转换的代码:
val testDF = hiveContext.sql("select distinct(trim(c1)),trim(c2) from default.table where trim(c1)!=''")
val testMap = scala.collection.mutable.Map(testDF.map(r => (r(0).toString,r(1).toString)).collectAsMap().toSeq: _*)
我对转换没有任何问题。但是,当我打印Dataframe
中的行数和Map
的大小时,我发现它们不匹配:
println("Map - "+testMap.size+" DataFrame - "+testDF.count)
//Map - 2359806 DataFrame - 2368295
我的想法是将Dataframes
转换为collections
并进行一些比较。我也从其他表中获取数据,但它们只是单列。我将它们转换为ArrayBuffer[String]
没有问题 - 计数匹配。
我不明白我为什么遇到testMap
的问题。通常,DF
中的计数行和Map
的大小应匹配,对吗?
是因为记录太多了吗?如何在DF
中将相同数量的记录导入Map
?
任何帮助将不胜感激。谢谢。
答案 0 :(得分:2)
我认为计数不匹配是由Map
中消除重复密钥(即城市名称)引起的。根据设计,Map
通过删除所有重复项来维护唯一键。例如:
val testDF = Seq(
("Newyork", 1),
("LA", 0),
("Chicago", 1),
("Newyork", 99)
).toDF("city", "value")
val testMap = scala.collection.mutable.Map(
testDF.rdd.map( r => (r(0).toString, r(1).toString)).
collectAsMap().toSeq: _*
)
// testMap: scala.collection.mutable.Map[String,String] =
// Map(Newyork -> 99, LA -> 0, Chicago -> 1)
您可能希望使用不同的集合类型或在Map键中包含标识字段以使其唯一。根据您的数据处理需求,您还可以通过groupBy
将数据汇总到类似地图的数据框中,如下所示:
testDF.groupBy("city").agg(count("value").as("valueCount"))
在此示例中,valueCount
的总数应与原始行数匹配。
答案 1 :(得分:0)
如果您向地图添加具有重复键的条目,则会自动删除重复项。所以你要比较的是:
println("Map - "+testMap.size+" DataFrame - "+testDF.select($"c1").distinct.count)