Tengo un PySpark dataframe

+-------+--------------+----+----+
|address|          date|name|food|
+-------+--------------+----+----+
|1111111|20151122045510| Yin|gre |
|1111111|20151122045501| Yin|gre |
|1111111|20151122045500| Yln|gra |
|1111112|20151122065832| Yun|ddd |
|1111113|20160101003221| Yan|fdf |
|1111111|20160703045231| Yin|gre |
|1111114|20150419134543| Yin|fdf |
|1111115|20151123174302| Yen|ddd |
|2111115|      20123192| Yen|gre |
+-------+--------------+----+----+

que quiero transformar a utilizar con pyspark.ml. Puedo usar un StringIndexer para convertir el nombre de la columna a una categoría numérica:

indexer = StringIndexer(inputCol="name", outputCol="name_index").fit(df)
df_ind = indexer.transform(df)
df_ind.show()
+-------+--------------+----+----------+----+
|address|          date|name|name_index|food|
+-------+--------------+----+----------+----+
|1111111|20151122045510| Yin|       0.0|gre |
|1111111|20151122045501| Yin|       0.0|gre |
|1111111|20151122045500| Yln|       2.0|gra |
|1111112|20151122065832| Yun|       4.0|ddd |
|1111113|20160101003221| Yan|       3.0|fdf |
|1111111|20160703045231| Yin|       0.0|gre |
|1111114|20150419134543| Yin|       0.0|fdf |
|1111115|20151123174302| Yen|       1.0|ddd |
|2111115|      20123192| Yen|       1.0|gre |
+-------+--------------+----+----------+----+

¿Cómo puedo transformar varias columnas con StringIndexer (por ejemplo, name y food, cada uno con su propio StringIndexer) y, a continuación, utilizar VectorAssembler para generar una función vectorial? O tengo que crear una StringIndexer para cada columna?

** EDIT **: Esto no es un duplicado porque necesito a este mediante programación para varios marcos de datos con diferentes nombres de columna. No se pueden utilizar las VectorIndexer o VectorAssembler debido a que las columnas no son numéricos.

** EDICIÓN 2**: UNA solución tentativa es

indexers = [StringIndexer(inputCol=column, outputCol=column+"_index").fit(df).transform(df) for column in df.columns ]

donde puedo crear una lista con tres dataframes, cada una idéntica a la original, además de la transformación de la columna. Ahora necesito que vengan a formar el final dataframe, pero que muy ineficiente.

  • Posibles duplicados de Codificar y reunir varias características en PySpark
  • Similares, pero no realmente. Él está haciendo una columna en un tiempo para cada cadena indexador y necesito hacer varias columnas al mismo tiempo, sin tener que hacer cada uno separado
  • Entonces no es posible. ¿Qué sería incluso la salida?
  • OK, eso es lo que estaba buscando. Voy código de una UDF entonces.
  • No quieres algo más como CountVectroizer?
  • Sí, sería similar a sklearn CountVectorizer, pero por varias columnas, no hay una lista en una columna.
  • Usted podría reunir las columnas con array("some_col", "other_col") y uso CountVectorizer pero no creo que realmente hacen mucho sentido.

InformationsquelleAutor Ivan | 2016-04-29

1 Comentario

  1. 46

    La mejor manera que he encontrado para hacerlo es combinar varios StringIndex en una lista y utilice un Pipeline para ejecutar todos ellos:

    from pyspark.ml import Pipeline
    from pyspark.ml.feature import StringIndexer
    indexers = [StringIndexer(inputCol=column, outputCol=column+"_index").fit(df) for column in list(set(df.columns)-set(['date'])) ]
    pipeline = Pipeline(stages=indexers)
    df_r = pipeline.fit(df).transform(df)
    df_r.show()
    +-------+--------------+----+----+----------+----------+-------------+
    |address|          date|food|name|food_index|name_index|address_index|
    +-------+--------------+----+----+----------+----------+-------------+
    |1111111|20151122045510| gre| Yin|       0.0|       0.0|          0.0|
    |1111111|20151122045501| gra| Yin|       2.0|       0.0|          0.0|
    |1111111|20151122045500| gre| Yln|       0.0|       2.0|          0.0|
    |1111112|20151122065832| gre| Yun|       0.0|       4.0|          3.0|
    |1111113|20160101003221| gre| Yan|       0.0|       3.0|          1.0|
    |1111111|20160703045231| gre| Yin|       0.0|       0.0|          0.0|
    |1111114|20150419134543| gre| Yin|       0.0|       0.0|          5.0|
    |1111115|20151123174302| ddd| Yen|       1.0|       1.0|          2.0|
    |2111115|      20123192| ddd| Yen|       1.0|       1.0|          4.0|
    +-------+--------------+----+----+----------+----------+-------------+
    • Tengo un bucle de iteración con reasignaciones dentro. Más feo de código en el universo.. Supongo que es hora de invertir un poco de esfuerzo y cambiar a Pipelines de una vez por todas!
    • ¿Usted realmente necesita fit en indexers? Se ejecuta fit en el pipeline de todos modos.
    • He probado esta solución, pero he encontrado esto hay diferencia con for-loop. Yo todavía tenía múltiples chispa de trabajo como para el bucle

Dejar respuesta

Please enter your comment!
Please enter your name here