Apache spark 使用Scala将列分配给Spark数据帧中的其他列
为了提高我的Scala技能和答案,我一直在研究这个优秀的问题: 我按照如下方式创建了修改后的代码,该代码可以正常工作,但我还有几个问题要问:Apache spark 使用Scala将列分配给Spark数据帧中的其他列,apache-spark,Apache Spark,为了提高我的Scala技能和答案,我一直在研究这个优秀的问题: 我按照如下方式创建了修改后的代码,该代码可以正常工作,但我还有几个问题要问: import spark.implicits._ import org.apache.spark.sql.functions._ val df = sc.parallelize(Seq( ("r1", 1, 1), ("r2", 6, 4), ("r3", 4, 1), ("r4", 1, 2) )).toDF(
import spark.implicits._
import org.apache.spark.sql.functions._
val df = sc.parallelize(Seq(
("r1", 1, 1),
("r2", 6, 4),
("r3", 4, 1),
("r4", 1, 2)
)).toDF("ID", "a", "b")
val uniqueVal = df.select("b").distinct().map(x => x.getAs[Int](0)).collect.toList
def myfun: Int => List[Int] = _ => uniqueVal
def myfun_udf = udf(myfun)
df.withColumn("X", myfun_udf( col("b") )).show
+---+---+---+---------+
| ID| a| b| X|
+---+---+---+---------+
| r1| 1| 1|[1, 4, 2]|
| r2| 6| 4|[1, 4, 2]|
| r3| 4| 1|[1, 4, 2]|
| r4| 1| 2|[1, 4, 2]|
+---+---+---+---------+
这是可行的,但:
- 我注意到b列放了两次
- 我也可以把第二个语句放在a列,得到同样的结果。那又有什么意义呢李>
- 如果我输入col ID,那么它将为null
- 所以,我想知道为什么第二列是输入
- 如何使其对所有列通用
所以,这是我在别处看到的代码,但我遗漏了一些东西。您显示的代码没有多大意义:
- 它是不可伸缩的-在最坏的情况下,每行的大小与大小成比例
- 正如你已经发现的,它根本不需要争论
- 它在编写时不需要(以及它不需要的重要内容)
(在2016-12-23 Spark 1.6和2.0上已经发布)udf
- 如果您仍然想使用
空变量就足够了udf
- 如果您有一个本地列表,并且确实希望使用
。对于单序列,使用带有空值功能的udf
:udf
概括为:val uniqueBVal:Seq[Int]=??? val addUniqueBValCol=udf(()=>uniqueBVal) df.withColumn(“X”,addUniqueBValCol())
导入scala.reflect.runtime.universe.TypeTag def addLiteral[T:TypeTag](xs:Seq[T])=udf(()=>xs) val x=addLiteral[Int](唯一值) df.withColumn(“X”,X())
- 最好不要使用
:udf
import org.apache.spark.sql.functions_ 带列的测向(“x”,数组(单列地图点亮:*)
- 截至
如何使其对所有列通用
正如一开始提到的,整个概念很难辩护。任一窗口功能(完全不可扩展)
或与聚合交叉连接(大多数情况下不可扩展)import org.apache.spark.sql.expressions.Window val w=窗口之间的行(窗口.unbounddReceiding,窗口.unboundedFollowing) df.select($“*”+:df.columns.map(c=>collect\u set(c).over(w).alias(s“${c}\u unique”):\u*)
但一般来说,如果在实际应用程序中出现这种情况,您必须重新考虑您的方法,除非您确实知道,列的基数很小并且有严格的上限val uniqueValues=df.select( df.columns映射(c=>collect_set(col(c))。别名(s“${c}\u unique”):_* ) df.交叉连接(唯一值)