我有两个数据帧,
val df1 = sqlContext.csvFile("/data/testData.csv")
val df2 = sqlContext.csvFile("/data/someValues.csv")
df1=
startTime name cause1 cause2
15679 CCY 5 7
15683 2 5
15685 1 9
15690 9 6
df2=
cause description causeType
3 Xxxxx cause1
1 xxxxx cause1
3 xxxxx cause2
4 xxxxx
2 Xxxxx
我希望将复杂函数getTimeCust
应用于cause1和cause2以确定最终原因,然后匹配df2中此最终原因代码的描述。我必须有一个新的df(或rdd),其中包含以下列:
startTime name cause descriptionCause
我的解决方案是
val rdd2 = df1.map(row => {
val (cause, descriptionCause) = getTimeCust(row.getInt(2), row.getInt(3), df2)
Row (row(0),row(1),cause,descriptionCause)
})
如果运行下面的代码我有一个NullPointerException
,因为df2不可见。
函数getTimeCust(Int, Int, DataFrame)
在地图之外运作良好。
答案 0 :(得分:2)
使用df1.join(df2, <join condition>)
将数据框连接在一起,然后从连接的数据框中选择所需的字段。
您不能在执行程序上运行的代码中使用spark的分布式结构(rdd,dataframe等)。
答案 1 :(得分:0)
尝试这样的事情:
def f1(cause1: Int, cause2: Int): Int = some logic to calculate cause
import org.apache.spark.sql.functions.udf
val dfCause = df1.withColumn("df1_cause", udf(f1)($"cause1", $"cause2"))
val dfJoined = dfCause.join(df2, on= df1Cause("df1_cause")===df2("cause"))
dfJoined.select("cause", "description").show()
答案 2 :(得分:0)
谢谢@Assaf。感谢您的回答和spark udf with data frame。我已经解决了这个问题。解决方案是:
val getTimeCust= udf((cause1: Any, cause2: Any) => {
var lastCause = 0
var categoryCause=""
var descCause=""
lastCause= .............
categoryCause= ........
(lastCause, categoryCause)
})
并将udf称为:
val dfWithCause = df1.withColumn("df1_cause", getTimeCust( $"cause1", $"cause2"))
最后加入
val dfFinale=dfWithCause.join(df2, dfWithCause.col("df1_cause._1") === df2.col("cause") and dfWithCause.col("df1_cause._2") === df2.col("causeType"),'outer' )