Pyspark: как выбрать значения до последнего из первого вхождения в массиве на основе совпадающих значений в другом столбце - PullRequest
0 голосов
/ 29 мая 2019

У меня есть фрейм данных, где мне нужно искать значение, присутствующее в одном столбце, т. Е. 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] 

Ответы [ 2 ]

3 голосов
/ 29 мая 2019

Начиная с 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. Надеюсь, это поможет.

0 голосов
/ 29 мая 2019

Это то, что вы хотите, я думаю, я также реализовал это на фиктивных данных:

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]|
+----+------------------------------+------------------------+

Дайте мне знать, если это работает для вас.

...