2016-05-24 2 views
8

私は以下の構造のスパークデータフレームを持っています。 bodyText_tokenには、トークン(処理された/単語のセット)があります。そして私は、私は各キーワードのリストに該当どのように多くのトークンをチェックし、既存のデータフレームの新しい列として結果を追加するために必要な定義されたキーワード データフレームの列と外部リストをwithColumnの下のudfに渡す

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

のネストされたリストを持っています。 例: tokens =["become", "farmer","rally","workers","student"] 結果は - > [1,2,0]

次の機能は期待通りに機能しました。

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 

機能にアクセスするためにudfをwithColumnで使用しましたが、エラーが発生します。私はそれが外部リストをudfに渡すことだと思います。外部リストとdatafram列をudfに渡してデータフレームに新しい列を追加する方法はありますか?

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

答えて

20

きれいな解決策は、クロージャを使用して追加の引数を渡すことです:

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()) 

これはkeyword_listの変更か、UDFでラップ機能を必要としません。このメソッドを使用して、任意のオブジェクトを渡すこともできます。これは、効率的なルックアップのために、たとえばsetsのリストを渡すために使用できます。

あなたの現在のUDFを使用して直接topic_wordsを渡したい場合は、最初のリテラルの列に変換する必要があります:あなたのデータや要件に応じて

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() 

代わり、より効率的な解決策があることができ、 UDF(爆発+集約+崩壊)やルックアップ(ハッシング+ベクタ操作)を必要としません。

7

次のいずれかの外部パラメータは、UDF(誰を助けるために微調整コード)

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

に渡すことができる場所これは動作しますが、UDFは、 'topic_wordsを持っていますので、私は、これは慎重になり正常に動作します'udfが定義された瞬間の値。 'topic_words'を変更してudfを再利用することはできません。udfが定義された時点で' topic_words'の値を使用します。 – CHP

関連する問題