dataframe列中动态长度为onehot编码的Pyspark字符串数组

dataframe列中动态长度为onehot编码的Pyspark字符串数组,pyspark,apache-spark-sql,transformer,Pyspark,Apache Spark Sql,Transformer,我想转换包含以下字符串的列: ["ABC","def","ghi"] ["Jkl","ABC","def"] ["Xyz","ABC"] 进入编码列,如下所示: [1,1,1,0,0] [1,1,0,1,0] [0,1,0,0,1] 在pyspark.ml.feature中有这样的类吗 编辑:在编码列中,第一个条目始终对应于值ABC等。1表示ABC存在,而0表示它不存在于相应的行中。您必须将单列中的列表扩展到多个n列,其中n是给定列表中的项数。然后可以使用将其转换为一个热编码特

我想转换包含以下字符串的列:

 ["ABC","def","ghi"] 
 ["Jkl","ABC","def"]
 ["Xyz","ABC"]
进入编码列,如下所示:

 [1,1,1,0,0]
 [1,1,0,1,0]
 [0,1,0,0,1]
在pyspark.ml.feature中有这样的类吗


编辑:在编码列中,第一个条目始终对应于值ABC等。1表示ABC存在,而0表示它不存在于相应的行中。

您必须将单列中的列表扩展到多个n列,其中n是给定列表中的项数。然后可以使用将其转换为一个热编码特征

请遵循文档中的示例:

from pyspark.ml.feature import OneHotEncoderEstimator

df = spark.createDataFrame([
    (0.0, 1.0),
    (1.0, 0.0),
    (2.0, 1.0),
    (0.0, 2.0),
    (0.0, 1.0),
    (2.0, 0.0)
], ["categoryIndex1", "categoryIndex2"])

encoder = OneHotEncoderEstimator(inputCols=["categoryIndex1", "categoryIndex2"],
                                 outputCols=["categoryVec1", "categoryVec2"])
model = encoder.fit(df)
encoded = model.transform(df)
encoded.show()
由于是无状态转换器,自v2.3以来已被弃用,因此在类别数可能与培训数据不同的新数据上不可用


这将帮助您拆分列表:

您必须将单个列中的列表扩展为多个n列,其中n是给定列表中的项目数。然后可以使用将其转换为一个热编码特征

请遵循文档中的示例:

from pyspark.ml.feature import OneHotEncoderEstimator

df = spark.createDataFrame([
    (0.0, 1.0),
    (1.0, 0.0),
    (2.0, 1.0),
    (0.0, 2.0),
    (0.0, 1.0),
    (2.0, 0.0)
], ["categoryIndex1", "categoryIndex2"])

encoder = OneHotEncoderEstimator(inputCols=["categoryIndex1", "categoryIndex2"],
                                 outputCols=["categoryVec1", "categoryVec2"])
model = encoder.fit(df)
encoded = model.transform(df)
encoded.show()
由于是无状态转换器,自v2.3以来已被弃用,因此在类别数可能与培训数据不同的新数据上不可用

这将帮助您拆分列表:

您可能可以使用,下面是一个示例:

更新:删除了在数组中删除重复项的步骤,您可以在设置CountVectorizer时设置binary=True:

from pyspark.ml.feature import CountVectorizer
from pyspark.sql.functions import udf, col

df = spark.createDataFrame([
        (["ABC","def","ghi"],)
      , (["Jkl","ABC","def"],)
      , (["Xyz","ABC"],)
    ], ['arr']
)
创建CountVectorizer模型:

cv = CountVectorizer(inputCol='arr', outputCol='c1', binary=True)

model = cv.fit(df)

vocabulary = model.vocabulary
# [u'ABC', u'def', u'Xyz', u'ghi', u'Jkl']
创建UDF以将向量转换为数组

udf_to_array = udf(lambda v: v.toArray().tolist(), 'array<double>')
您可能可以使用,下面是一个示例:

更新:删除了在数组中删除重复项的步骤,您可以在设置CountVectorizer时设置binary=True:

from pyspark.ml.feature import CountVectorizer
from pyspark.sql.functions import udf, col

df = spark.createDataFrame([
        (["ABC","def","ghi"],)
      , (["Jkl","ABC","def"],)
      , (["Xyz","ABC"],)
    ], ['arr']
)
创建CountVectorizer模型:

cv = CountVectorizer(inputCol='arr', outputCol='c1', binary=True)

model = cv.fit(df)

vocabulary = model.vocabulary
# [u'ABC', u'def', u'Xyz', u'ghi', u'Jkl']
创建UDF以将向量转换为数组

udf_to_array = udf(lambda v: v.toArray().tolist(), 'array<double>')

谢谢你的回答。带有onehotencoder的部件很好。我编辑了我的问题。我的问题是,我不知道我有多少个条目,而且顺序可能是随机的。如果我使用您链接的拆分解决方案,在最坏的情况下,我会得到一个可以包含所有值的column1。还有一个列2,可能又是所有的值。我想你必须将列表转换为相同的长度,然后将其拆分,除非你可以编写一个udf或一个通用python函数来对列表进行热编码,你可以通过相同的udf应用它。@pissall,如果OP需要数组而不是向量,不管怎样,他可能不得不使用udf。谢谢你的回答。带有onehotencoder的部件很好。我编辑了我的问题。我的问题是,我不知道我有多少个条目,而且顺序可能是随机的。如果我使用您链接的拆分解决方案,在最坏的情况下,我会得到一个可以包含所有值的column1。还有一个列2,可能又包含了所有值。我认为您必须将列表转换为相同的长度并进行拆分,除非您可以编写一个udf或通用python函数对列表进行热编码,您可以通过相同的udf应用该函数。@pissall,如果OP需要数组而不是向量,他可能无论如何都必须使用udf。