我有一个具有以下架构的数据框 -
|-- ID: string (nullable = true)
|-- VALUES: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- _v1: string (nullable = true)
| | |-- _v2: string (nullable = true)
VALUES就像 -
[["ABC","a"],["PQR","c"],["XYZ","b"],["TUV","d"]]
[["PQR","g"]]
[["TUV","f"],["ABC","e"]]
我根据_v1的值从这个数组中选择一个结构。这些值中有一个层次结构,如 -
" ABC" - > " XYZ" - > " PQR" - > " TUV"
现在,如果" TUV"如果存在,我们将选择" TUV"在它的_v1。否则,我们将检查" PQR"。如果" PQR"走了,走了。否则检查" XYZ"等等。
结果df应该看起来像 - (现在是StructType,而不是Array [Struct])
["TUV","d"]
["PQR","g"]
["TUV","f"]
有人可以指导我如何通过创建一个udf来解决这个问题? 提前谢谢。
答案 0 :(得分:1)
你可以做类似下面的事情
$array = ['PromotionIds' => Array (
'PromotionId' => Array (
0 => 'Amazon PLCC Free-Financing Universal Merchant MP-rachmit-1507891499711',
1 => 'Amazon PLCC Free-Financing Universal Merchant Script-1507895115492'
)
)];
$result = [];
foreach ($array['PromotionIds'] as $key => $value) {
$result[$key]=implode(',', $value);
}
echo "<pre>";
print_r($result);
echo "</pre>";
exit;
您应该有以下输出
import org.apache.spark.sql.functions._
def getIndex = udf((array : mutable.WrappedArray[String]) => {
if(array.contains("TUV")) array.indexOf("TUV")
else if(array.contains("PQR")) array.indexOf("PQR")
else if(array.contains("XYZ")) array.indexOf("XYZ")
else if(array.contains("ABC")) array.indexOf("ABC")
else 0
})
df.select($"VALUES"(getIndex($"VALUES._v1")).as("selected"))
我希望答案很有帮助
<强>更新强>
您可以使用+--------+
|selected|
+--------+
|[TUV,d] |
|[PQR,g] |
|[TUV,f] |
+--------+
表示法选择struct
列的元素。此处.
正在选择$"VALUES._v1"
的所有_v1
,并按相同的顺序将其struct
传递给udf
。
例如:对于Array
,[["ABC","a"],["PQR","c"],["XYZ","b"],["TUV","d"]]
会返回$"VALUES._v1"
,并传递给["ABC","PQR","XYZ","TUV"]
函数
在udf
函数内部,返回字符串匹配的数组的索引。例如:for [&#34; ABC&#34;,&#34; PQR&#34;,&#34; XYZ&#34;,&#34; TUV&#34;],&#34; TUV&#34;匹配所以它将返回3.
对于第一行,udf
将返回getIndex($"VALUES._v1")
,因此3
相当于$"VALUES"(getIndex($"VALUES._v1")
,这是$"VALUES"(3)
的第四个元素,即{{1} }。
我希望解释清楚。
答案 1 :(得分:1)
只要每行最多只包含一个_v1
值一次,这就应该有效。 UDF
将返回hierarchy
列表中最佳值的索引。然后,将选择_v1
中包含此值的stuct并将其放入“select”列。
val hierarchy = List("TUV", "PQR", "XYZ", "ABC")
val findIndex = udf((rows: Seq[String]) => {
val s = rows.toSet
val best = hierarchy.filter(h => s contains h).head
rows.indexOf(best)
})
df.withColumn("select", $"VALUES"(findIndex($"VALUES._v2")))
订单使用了一个列表,可以很容易地扩展到4个以上的值。