我有一个问题,我想检查一个字符串数组是否包含另一列中的字符串。我目前正在使用下面的代码,这是一个错误。
.withColumn("is_designer_present", when(array_contains(col("list_of_designers"),$"dept_resp"),1).otherwise(0))
错误:
java.lang.RuntimeException: Unsupported literal type class org.apache.spark.sql.ColumnName dept_resp
at org.apache.spark.sql.catalyst.expressions.Literal$.apply(literals.scala:77)
答案 0 :(得分:3)
您可以编写udf
函数来完成工作
import org.apache.spark.sql.functions._
def stringContains = udf((array: collection.mutable.WrappedArray[String], str: String) => array.contains(str))
df.withColumn("is_designer_present", when(stringContains(col("list_of_designers"), $"dept_resp"),1).otherwise(0))
您可以从udf
函数本身返回适当的值,这样您就不必使用when
函数
import org.apache.spark.sql.functions._
def stringContains = udf((array: collection.mutable.WrappedArray[String], str: String) => if (array.contains(str)) 1 else 0)
df.withColumn("is_designer_present", stringContains(col("list_of_designers"), $"dept_resp"))
答案 1 :(得分:2)
使用Spark 1.6,您可以将array_contains()
作为字符串包装到expr()
函数中:
import org.apache.spark.sql.functions.expr
.withColumn("is_designer_present",
when(expr("array_contains(list_of_designers, dept_resp)"), 1).otherwise(0))
array_contains
中的expr
形式可以接受列作为第二个参数。
答案 2 :(得分:0)
你可以使用explode在没有UDF的情况下完成。
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<p></p>
<button class="btn btn-outline-primary" data-toggle="modal" data-target="#insertData">Insert Data</button>
<!-- Modal -->
<div class="modal fade" id="insertData" tabindex="-1" role="dialog" aria-labelledby="insertLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="insertLabel">Insert Data</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form>
<div class="modal-body">
<form>
<div class="form-group">
<label for="nm">Full Name</label>
<input type="email" class="form-control" id="nm" aria-describedby="emailHelp" placeholder="Full Name">
</div>
<div class="form-group">
<label for="em">Email</label>
<input type="password" class="form-control" id="em" placeholder="Email">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" onclick="saveData()" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
<p></p>
</div>
</body>
</html>
然后你去,如果结果&gt; 0然后&#34; dept_rest&#34;包含值。
答案 3 :(得分:0)
我知道这是一个有点老的问题,但我发现自己陷入了类似的困境,并找到了以下解决方案。它使用 Spark 原生函数(因此它不会受到与 UDF 相关的性能回归的影响,并且它不依赖于字符串表达式(难以维护)。
def array_contains_column(arrayColumn: Column, valueColumn: Column): Column = {
new Column(ArrayContains(arrayColumn.expr, valueColumn.expr))
}
// ...
df.withColumn(
"is_designer_present",
when(
array_contains_column(col("list_of_designers"),col("dept_resp")),
1
).otherwise(0)
)