2017-08-25 62 views
0

如何在pyspark中应用索引器,但是按字母顺序排列类别?应用StringIndexer PySpark数据框但按字母顺序排列

我有我的索引值的字典,应用Stringindexer后,但我想命令它不同。

index_df = StringIndexer(inputCol="gender", outputCol="genderIndex") 

meta = [f.metadata for f in index_df.schema.fields if f.name == "genderIndex"] 
meta 
[{u'ml_attr': {u'name': u'genderIndex', 
    u'type': u'nominal', 
    u'vals': [u'Male', u'Female']}}] 

a=dict(enumerate(meta[0]["ml_attr"]["vals"])) 
a= 
{0: u'Male', 1: u'Female'} 

但是,例如,我想女性为0,并且如果它是一个,B,C

我想A = 0,B = 1,C = 2,等等。

+0

StringIndexer根据标签频率为列标签提供索引。对于你的情况,认为我们可能不得不编码自定义变压器来做到这一点。 – Suresh

+0

我不知道您的用例,但如果您要将索引列保存到字典中,并且不打算将它用于ML管道,请订购该列并执行密集排名。这可能会帮助你。 – Suresh

回答

0

在spark 2.3.0中,spark的StringIndexer将获得stringOrderType参数(related jira issue),但在< 2.3.0中,您将需要创建自定义转换器。例如,您可以盖特所有值,加上指数,初始DF加盟,像这样:

from pyspark.sql.window import Window 

df = spark.createDataFrame([(10, 'b'), (20, 'b'), (30, 'c'), 
          (40, 'c'), (50, 'c'), (60, 'a')], ['col1', 'col2']) 
col2_index = df.select('col2').distinct() \ 
    .withColumn('col2Index', row_number().over(Window.orderBy('col2')) - 1) 
col2_index.show() 

+----+---------+ 
|col2|col2Index| 
+----+---------+ 
| a|  0| 
| b|  1| 
| c|  2| 
+----+---------+ 

df.join(col2_index, 'col2').show() 

+----+----+---------+ 
|col2|col1|col2Index| 
+----+----+---------+ 
| c| 30|  2| 
| c| 40|  2| 
| c| 50|  2| 
| b| 10|  1| 
| b| 20|  1| 
| a| 60|  0| 
+----+----+---------+ 

OR,如果你不关心已经变压器字典创建的,你可以只使用dense_rank作为@Suresh中发现评论:

df.withColumn('col2Index', dense_rank().over(Window.orderBy('col2')) - 1).show()