7

当我在 Spark 中使用 onehotencoder 时,我会得到第四列的结果,这是一个稀疏向量。

// +---+--------+-------------+-------------+
// | id|category|categoryIndex|  categoryVec|
// +---+--------+-------------+-------------+
// |  0|       a|          0.0|(3,[0],[1.0])|
// |  1|       b|          2.0|(3,[2],[1.0])|
// |  2|       c|          1.0|(3,[1],[1.0])|
// |  3|      NA|          3.0|    (3,[],[])|
// |  4|       a|          0.0|(3,[0],[1.0])|
// |  5|       c|          1.0|(3,[1],[1.0])|
// +---+--------+-------------+-------------+

但是,我想要的是为类别生成 3 列,就像它在熊猫中的工作方式一样。

>>> import pandas as pd
>>> s = pd.Series(list('abca'))
>>> pd.get_dummies(s)
   a  b  c
0  1  0  0
1  0  1  0
2  0  0  1
3  1  0  0
4

2 回答 2

15

Spark 的 OneHotEncoder 创建一个稀疏向量列。要创建类似于 pandas OneHotEncoder 的输出列,我们需要为每个类别创建一个单独的列。我们可以在 pyspark 数据框的withColumn函数的帮助下通过传递一个 udf 作为参数来做到这一点。对于前 -

from pyspark.sql.functions import udf,col
from pyspark.sql.types import IntegerType


df = sqlContext.createDataFrame(sc.parallelize(
        [(0,'a'),(1,'b'),(2,'c'),(3,'d')]), ('col1','col2'))

categories = df.select('col2').distinct().rdd.flatMap(lambda x : x).collect()
categories.sort()
for category in categories:
    function = udf(lambda item: 1 if item == category else 0, IntegerType())
    new_column_name = 'col2'+'_'+category
    df = df.withColumn(new_column_name, function(col('col2')))

print df.show()

输出-

+----+----+------+------+------+------+                                         
|col1|col2|col2_a|col2_b|col2_c|col2_d|
+----+----+------+------+------+------+
|   0|   a|     1|     0|     0|     0|
|   1|   b|     0|     1|     0|     0|
|   2|   c|     0|     0|     1|     0|
|   3|   d|     0|     0|     0|     1|
+----+----+------+------+------+------+

我希望这有帮助。

于 2017-06-22T18:16:40.723 回答
1

无法发表评论,因为我没有声誉积分,所以改为回答问题。

这实际上是火花管道和变压器最好的事情之一!我不明白为什么您需要以这种格式获取它。你能详细说明吗?

于 2017-03-19T09:00:52.453 回答