2016-05-18 20 views
3

私はPySparkを使用します。ベクトルの列を2つの列に分割する方法は?

スパークMLのランダムフォレスト出力DataFrameには、2つの値を持つベクトルである「確率」列があります。出力データフレームに「prob1」と「prob2」という2つの列を追加し、ベクトルの最初の値と2番目の値に対応させます。

私は次のことを試してみた:

output2 = output.withColumn('prob1', output.map(lambda r: r['probability'][0])) 

を私は「COLは列でなければなりません」というエラーが発生します。

ベクトルの列をその値の列に変換する方法に関する提案はありますか?

答えて

1

1つのUDFを使用して最初の値を抽出し、別の値を抽出することができます。その後、ランダムフォレストデータフレームの出力で選択呼び出しでUDFを使用することができます。例:

from pyspark.sql.functions import udf, col 

split1_udf = udf(lambda value: value[0], FloatType()) 
split2_udf = udf(lambda value: value[1], FloatType()) 
output2 = randomForrestOutput.select(split1_udf(col("probability")).alias("c1"), 
            split2_udf(col("probability")).alias("c2")) 

これはあなたのコラム確率に格納されているリストにおける第1および第2の値に対応する列C1、C2とを持つデータフレームOUTPUT2を与える必要があります。

+1

私はあなたの提案を試みたが、それは、ここで言及したようなエラーを生成:http://stackoverflow.com/questions/29910708/pyspark-py4j-pickleexception-expected-zero-arguments-for-クラスの構築 – Petrichor

2

私は上記の提案の問題を考え出しました。 pysparkでは、「密ベクトルは単にNumPy配列オブジェクトとして表現される」ので、問題はPythonとNumpy型である。 numpy.float64をpython floatにキャストするには.item()を追加する必要があります。

次のコードは動作します:

split1_udf = udf(lambda value: value[0].item(), FloatType()) 
split2_udf = udf(lambda value: value[1].item(), FloatType()) 

output2 = randomforestoutput.select(split1_udf('probability').alias('c1'), split2_udf('probability').alias('c2')) 

か、元のデータフレームにこれらの列を追加する:

randomforestoutput.withColumn('c1', split1_udf('probability')).withColumn('c2', split2_udf('probability')) 
2

は同じ問題を抱えてあなたはn個を持っている場合、以下のコードは、状況に合わせて調整されます長さベクトル。

splits = [udf(lambda value: value[i].item(), FloatType()) for i in range(n)] 
out = tstDF.select(*[s('features').alias("Column"+str(i)) for i, s in enumerate(splits)]) 
関連する問題