Solumn

2016-05-24 29 views
8

altında bir veri çerçeve sütunu ve harici listeyi udf'ye aktarma Aşağıdaki yapıda bir kıvılcım veri çerçevem ​​var. BodyText_token, tokenlere (işlenmiş/kelime kümesi) sahiptir. Ve ben her bir anahtar kelime listesi altında düşmek kaç belirteçleri kontrol etmek ve mevcut dataframe yeni sütun olarak sonuç eklemek için gerekli kelime tanımlı Solumn

root 
|-- id: string (nullable = true) 
|-- body: string (nullable = true) 
|-- bodyText_token: array (nullable = true) 

keyword_list=['union','workers','strike','pay','rally','free','immigration',], 
['farmer','plants','fruits','workers'],['outside','field','party','clothes','fashions']] 

iç içe geçmiş bir listesi var. Ör .: tokens =["become", "farmer","rally","workers","student"] sonucu -> [1,2,0]

Aşağıdaki işlev beklendiği gibi çalışmıştır.

def label_maker_topic(tokens,topic_words): 
    twt_list = [] 
    for i in range(0, len(topic_words)): 
     count = 0 
     #print(topic_words[i]) 
     for tkn in tokens: 
      if tkn in topic_words[i]: 
       count += 1 
     twt_list.append(count) 

    return twt_list 

İşleve erişmek için, işlev alanına erişmek için udf kullandım ve bir hata alıyorum. Bence harici bir listeyi bir udf'ye aktarmak. Dış listeyi ve datafram sütununu bir udf'ye aktarabilir ve veri çerçeveme yeni bir sütun ekleyebilir miyim?

topicWord = udf(label_maker_topic,StringType()) 
myDF=myDF.withColumn("topic_word_count",topicWord(myDF.bodyText_token,keyword_list)) 

cevap

20

en temiz çözüm kapatılması kullanarak ek argümanlar geçmektir:

def make_topic_word(topic_words): 
    return udf(lambda c: label_maker_topic(c, topic_words)) 

df = sc.parallelize([(["union"],)]).toDF(["tokens"]) 

(df.withColumn("topics", make_topic_word(keyword_list)(col("tokens"))) 
    .show()) 

Bu keyword_list herhangi bir değişiklik veya UDF ile sarın işlevini gerektirmez. Rasgele bir nesneyi geçmek için bu yöntemi de kullanabilirsiniz. Bu, verimli aramalar için örneğin sets'un bir listesini geçmek için kullanılabilir. Eğer mevcut UDF kullanmak ve topic_words geçmek istiyorsanız

doğrudan ilk edebi bir sütun dönüştürmek gerekir:

from pyspark.sql.functions import array, lit 

ks_lit = array(*[array(*[lit(k) for k in ks]) for ks in keyword_list]) 
df.withColumn("ad", topicWord(col("tokens"), ks_lit)).show() 

verileriniz ve gereksinimleri vardır can alternatif, daha verimli çözümler bağlı olarak, UDF'leri (patlatma + toplama + daraltma) veya aramaları (hashing + vektör işlemleri) gerektirmez. udf `topic_words sahip olacağından dolayı, herhangi bir dış parametre UDF geçirilebilir

7

aşağıdaki eserlerini ince Bu işleri

topicWord=udf(lambda tkn: label_maker_topic(tkn,topic_words),StringType()) 
myDF=myDF.withColumn("topic_word_count",topicWord(myDF.bodyText_token)) 
+0

(büküverilmiş bir kod herkes yardımcı olmak için) ama bu dikkatli olurdu 'şu anda udf tanımlanmış değer. Dolayısıyla, 'topic_words' değiştirilerek ve daha sonra udf ile yeniden kullanılması işe yaramaz - bu, udf'nin tanımlandığı zamanda hala' topic_words 'değerini kullanır. – CHP