我正在学习Scala中的Spark,源于严重的Python滥用,我得到了java.lang.NullPointerException
,因为我是以python的方式工作的。
我说每个3x形状为4x2的数据帧,第一列始终是索引0、1、2、3,第二列是某种二进制特征。最终目标是拥有一个4x4数据帧,其中包含所有单个数据帧的连接。在python中,我先定义一些主df,然后在中间的df上循环,在每个循环中将结果联接的数据帧分配给主数据帧变量名(丑陋):
dataframes = [temp1, temp2, temp3]
df = pd.DataFrame(index=[0,1,2,3]) # Master df
for temp in dataframes:
df = df.join(temp)
在Spark中,这种方法不能很好地发挥作用:
q = "select * from table"
val df = sql(q)
很明显
scala> val df = df.join(sql(q))
<console>:33: error: recursive value df needs type
val df = df.join(sql(q))
好吧:
scala> val df:org.apache.spark.sql.DataFrame = df.join(sql(q))
java.lang.NullPointerException
... 50 elided
我认为我很可能没有按照功能方式进行操作。所以我尝试了(最丑!):
scala> :paste
// Entering paste mode (ctrl-D to finish)
sql(q).
join(sql(q), "device_id").
join(sql(q), "device_id").
join(sql(q), "device_id")
// Exiting paste mode, now interpreting.
res128: org.apache.spark.sql.DataFrame = [device_id: string, devtype: int ... 3 more fields]
这看起来很丑陋,不雅和初学者。实现此目标的适当的功能性Scala方法是什么?
答案 0 :(得分:2)
foldLeft
:
val dataframes: Seq[String] = ???
val df: Dataset[Row] = ???
dataframes.foldLeft(df)((acc, q) => acc.join(sql(q)))
如果您正在寻找与您的Python代码等效的命令:
var dataframes: Seq[String] = ??? // IMPORTANT: var
for (q <- dataframes ) { df = df.join(sql(q)) }
答案 1 :(得分:1)
更简单
val dataframes: Seq[String] = ???
dataframes.reduce(_ join _)