Méthode de transformation PySpark avec Vector Assembler
J'ai un Spark DataFrame et j'aimerais utiliser Vector Assembler pour créer une colonne "features".
from pyspark.ml.feature import VectorAssembler
assembler = VectorAssembler(inputCols=sel_cols, outputCol='features')
transformed_data = assembler.transform(sdf)
sel_cols se compose d'une liste de 150 éléments de type chaîne, qui se présente comme suit:
['ASP.NET Core',
'ASP.NET MVC',
'AWS',
'AWS DynamoDB',
'AWS EMR',
'AWS SDK',
'Adobe Photoshop',
'Agile',
'Agile software development29',
'Ajax',
'Amazon CloudFront CDN',
'Amazon EC2',
'Android',
'Angular',
'AngularJS',
'Apache',
'Apache Hive',
'Apache Spark',
'Atom',...]
Et sdf.columns, se compose de 340 éléments et se présente comme suit:
['.NET',
'.NET 4',
'.NET Core',
'ADO.NET',
'AFNetworking',
'API Architecture',
'API Design',
'API Development',
'APIs',
'ASP.NET',
'ASP.NET Core',
'ASP.NET MVC',
'ASP.NET Web API',
'AWS',
'AWS DynamoDB',...]
J'obtiens cette erreur en appliquant transformer_data = assembler.transform (sdf):
AnalysisException: Cannot resolve column name "ASP.NET Core" among (.NET, .NET 4, .NET Core, ADO.NET, AFNetworking, API Architecture, API Design, API Development, APIs, ASP.NET, ASP.NET Core, ASP.NET MVC, ASP.NET Web API, AWS, AWS DynamoDB, AWS EC2, AWS ECS, AWS EMR, AWS HA, AWS Lambda, AWS RDS, AWS S3, AWS SDK, Adobe Illustrator,...
Comme indiqué, "ASP.NET Core" fait certainement partie de mes sdf.columns et pour autant que je sache, passer sel_cols comme une liste de chaînes à inputCols de VectorAssembler devrait fonctionner ... J'apprécierais vraiment tout aperçu car je n'ai pas travaillé avec Spark DF avant :)
Je vous remercie!
Réponses
Le VectorAssembler ne peut pas gérer les colonnes avec un espace ou un point dans le nom de la colonne. Une autre réponse de ma part fournit des informations techniques sur les raisons pour lesquelles cela ne fonctionne pas.
La seule option est de renommer les colonnes:
#build a dict (orginal column name: new column name)
mapping = {col: col.replace('.','_').replace(' ', '_') for col in sel_columns}
#select all columns and create an alias if there is a mapping for this column
df_renamed = df.select([F.col('`'+c+'`').alias(mapping.get(c, c)) for c in df.columns])
#create a VectorAssembler that uses the renamed columns as input
assembler = VectorAssembler(inputCols=list(mapping.values()), outputCol='features')
transformed_data = assembler.transform(df_renamed)