Примените UDF к подмножествам pyspark dataframe

1

У меня есть Dataframe, как показано ниже, содержащий два отсортированных списка строк для каждой возможной комбинации key1 и key2.

df=
+----+------------+-------+-------+
|key1|        key2| value1| value2|
+----+------------+-------+-------+
| 'a'|  '10,0,10' |  'abc'|  'abc'|
| 'a'|  '10,0,10' |  'aab'|  'aab'|
| 'a'|  '10,0,10' |  'acb'|  'acb'|
| 'a'|  '10,0,20' |  'abc'|  'abc'|
| 'a'|  '10,0,20' |  'acb'|  'aab'|
| 'a'|  '10,0,20' |  'aab'|  'acb'|
| 'b'|  '10,0,10' |  'bcd'|  'bcd'|
| 'b'|  '10,0,10' |  'bbc'|  'bdc'|
| 'b'|  '10,0,10' |  'bdc'|  'bbc'|
|...

Теперь я хочу применить funcion следующим образом:

for c in [x for x in df.select('key1').distinct().collect()]:
    for s in [x for x in df.select('key2').distinct().collect()]:
       jaccard_sim([x for x in df.select('value1').filter(df['key1']==c).filter(df['key2']==s).collect()], 
              [x for x in df.select('value2').filter(df['key1']==c).filter(df['key2']==s).collect()])

Но так как я хочу использовать способность искры распараллеливать выполнение, я думаю, что вышеупомянутая реализация может быть отчасти глупо;) У кого-нибудь есть идея, как ее решить?

Фон состоит в том, что у меня есть отсортированный список (value1) для каждой комбинации key1 и key2, который я хочу сравнить с контрольным списком на ключ 1 (значение2) и вычислить сходство jaccard между списками. Если кто-то вообще предлагает (лучше) предложение о том, как это сделать с помощью pyspark, я бы действительно его воспринял! Спасибо:)

Теги:
apache-spark-sql
pyspark

1 ответ

1
Лучший ответ

Вы можете подойти так,

import pyspark.sql.functions as F

def convert_form(x):
    print type(x)
    val1 = [y['value1'] for y in x]
    val2 = [y['value2'] for y in x]
    return [val1, val2]

jaccard_udf = F.udf(lambda x: jaccard_sim(*convert_form(x)) ) #assuming you have jaccard_sim function

df = df.select('key1', 'key2', F.struct('value1','value2').alias('values'))\
       .groupby('key1', 'key2').agg(F.collect_list('values').alias('collected_col'))\
       .withColumn('jaccard_distance', jaccard_udf(F.col('collected_col')) )

df.show()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню