如何将向量列拆分为两列?

时间:2016-05-18 23:32:30

标签: apache-spark pyspark apache-spark-ml

我使用PySpark。

Spark ML的随机森林输出DataFrame有一列"概率"这是一个有两个值的向量。我只想在输出DataFrame中添加两列," prob1"和" prob2",对应于向量中的第一个和第二个值。

我尝试过以下方法:

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

但是我得到的错误是' col应该是Column'。

有关如何将一列向量转换为其值列的任何建议吗?

4 个答案:

答案 0 :(得分:2)

我发现了上述建议的问题。在pyspark中,“密集向量简单地表示为NumPy数组对象”,因此问题在于python和numpy类型。需要添加.item()将numpy.float64强制转换为python float。

以下代码有效:

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

答案 1 :(得分: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)])

答案 2 :(得分:1)

您可能希望使用一个UDF来提取第一个值,而使用另一个UDF来提取第二个值。然后,您可以在随机forrest数据帧的输出上使用UDF和select调用。例如:

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

这应该为您提供一个数据帧输出2,其中列c1和c2对应于列概率中存储的列表中的第一个和第二个值。

答案 3 :(得分:0)

我尝试了@Rookie Boy的循环,但是似乎udf循环拆分对我不起作用。 我做了一些修改。

out = df
for i in range(len(n)):
    splits_i = udf(lambda x: x[i].item(), FloatType())
    out = out.withColumn('{col_}'.format(i), splits_i('probability'))
out.select(*['col_{}'.format(i) for i in range(3)]).show()