Pyspark:如何根据另一列中的匹配值从数组中的第一次出现中选择直到最后的值
Posted
技术标签:
【中文标题】Pyspark:如何根据另一列中的匹配值从数组中的第一次出现中选择直到最后的值【英文标题】:Pyspark : How to pick the values till last from the first occurrence in an array based on the matching values in another column 【发布时间】:2019-05-29 10:28:24 【问题描述】:我有一个数据框,我需要在其中搜索一个列中存在的值,即另一列中的 StringType,即 ArrayType,但我想从第二列中选择值,直到第一次出现的数组中的最后一个值柱子。
下面举例说明:
输入DF如下:
Employee_Name|Employee_ID|Mapped_Project_ID
Name1|E101|[E101, E102, E103]
Name2|E102|[E101, E102, E103]
Name3|E103|[E101, E102, E103, E104, E105]
输出 DF 应该如下所示:
Employee_Name|Employee_ID|Mapped_Project_ID
Name1|E101|[E101, E102, E103]
Name2|E102|[E102, E103]
Name3|E103|[E103, E104, E105]
【问题讨论】:
【参考方案1】:从 Spark 2.4 开始,您可以使用 array_position
和 slice
函数:
import pyspark.sql.functions as f
from pyspark.sql.functions import array_position
from pyspark.sql.functions import slice
df = spark.createDataFrame([(["c", "b", "a","e","f"],'a')], ['arraydata','item'])
df.select(df.arraydata, f.expr("slice(arraydata,array_position(arraydata, item),size(arraydata))").alias("res")).show()
+---------------+---------+
| arraydata| res|
+---------------+---------+
|[c, b, a, e, f]|[a, e, f]|
+---------------+---------+
请把它翻译成你的 df colnames。希望这会有所帮助。
【讨论】:
感谢@mrjoseph 的解决方案,但不幸的是我在我的项目中使用Spark 2.3。【参考方案2】:这就是我想的你想要的,我也在虚拟数据上实现了它:
import pyspark.sql.types as T
import pyspark.sql.functions as F
df = sqlContext.createDataFrame([['E101',["E101", "E102", "E103", "E104", "E105"]]],["eid", "mapped_eid"])
df.persist()
df.show(truncate = False)
+----+------------------------------+
|eid |mapped_eid |
+----+------------------------------+
|E101|[E101, E102, E103, E104, E105]|
+----+------------------------------+
@F.udf(returnType=T.ArrayType(T.StringType()))
def find_element(element,temp_list):
count = 0
res = []
for i in range(len(temp_list)):
if (count == 0) and (temp_list[i] != element):
count = 1
res.append(temp_list[i])
elif count == 1:
res.append(temp_list[i])
return res
df.withColumn(
"res_col",
find_element(F.col("eid"), F.col("mapped_eid"))
).show(truncate = False)
+----+------------------------------+------------------------+
|eid |mapped_eid |res_col |
+----+------------------------------+------------------------+
|E101|[E101, E102, E103, E104, E105]|[E102, E103, E104, E105]|
+----+------------------------------+------------------------+
让我知道这是否适合你。
【讨论】:
我们可以避免使用 UDF。我想在不使用 UDF 的情况下工作 不,我们不能不使用 UDF,这不是最佳方法,唯一的其他选择是拆分数组不会推荐它 使用新函数可以避免使用 udfs(从 Spark 2.4 开始): slice 和 array_position: spark.apache.org/docs/latest/api/python/…以上是关于Pyspark:如何根据另一列中的匹配值从数组中的第一次出现中选择直到最后的值的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 PySpark 数据框的另一列中的值修改列? F.当边缘情况
使用 PySpark 连接与另一列中的两列确定的范围相匹配的数据框