[英]How to pass whole Row to UDF - Spark DataFrame filter
我正在为具有大量内部结构的复杂JSON数据集编写过滤函数。 传递单个列太麻烦了。
所以我声明了以下UDF:
val records:DataFrame = = sqlContext.jsonFile("...")
def myFilterFunction(r:Row):Boolean=???
sqlc.udf.register("myFilter", (r:Row)=>myFilterFunction(r))
直觉我觉得它会像这样工作:
records.filter("myFilter(*)=true")
实际的语法是什么?
在调用函数时,必须使用struct()
函数构造行,请按照以下步骤操作。
导入行,
import org.apache.spark.sql._
定义UDF
def myFilterFunction(r:Row) = {r.get(0)==r.get(1)}
注册UDF
sqlContext.udf.register("myFilterFunction", myFilterFunction _)
创建dataFrame
val records = sqlContext.createDataFrame(Seq(("sachin", "sachin"), ("aggarwal", "aggarwal1"))).toDF("text", "text2")
使用UDF
records.filter(callUdf("myFilterFunction",struct($"text",$"text2"))).show
当你想要将所有列传递给UDF时。
records.filter(callUdf("myFilterFunction",struct(records.columns.map(records(_)) : _*))).show
结果:
+------+------+
| text| text2|
+------+------+
|sachin|sachin|
+------+------+
scala> inputDF
res40: org.apache.spark.sql.DataFrame = [email: string, first_name: string ... 3 more fields]
scala> inputDF.printSchema
root
|-- email: string (nullable = true)
|-- first_name: string (nullable = true)
|-- gender: string (nullable = true)
|-- id: long (nullable = true)
|-- last_name: string (nullable = true)
现在,我想根据性别字段过滤行。 我可以通过使用.filter($"gender" === "Male")
来实现这一点,但我想使用.filter(function)
。
所以,定义了我的匿名函数
val isMaleRow = (r:Row) => {r.getAs("gender") == "Male"}
val isFemaleRow = (r:Row) => { r.getAs("gender") == "Female" }
inputDF.filter(isMaleRow).show()
inputDF.filter(isFemaleRow).show()
我觉得可以以更好的方式完成需求,即不声明为UDF并调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.