PySpark-Transformationsmethode mit Vector Assembler

Sep 26 2020

Ich habe einen Spark DataFrame und möchte Vector Assembler verwenden, um eine Spalte "Features" zu erstellen.

from pyspark.ml.feature import VectorAssembler

assembler = VectorAssembler(inputCols=sel_cols, outputCol='features')

transformed_data = assembler.transform(sdf)

sel_cols besteht aus einer Liste von 150 Elementen vom Typ string, die wie folgt aussieht:

['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',...]

Und sdf.columns besteht aus 340 Elementen und sieht wie folgt aus:

['.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',...]

Ich erhalte diesen Fehler beim Anwenden von transformierter_Daten = 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,...

Wie gezeigt, gehört "ASP.NET Core" definitiv zu meinen sdf.columns, und soweit ich es verstehe, sollte es funktionieren, sel_cols als Liste von Zeichenfolgen an die inputCols von VectorAssembler zu übergeben ... Würde mich über jeden Einblick wirklich freuen, da ich nicht gearbeitet habe mit Spark DF's vorher :)

Vielen Dank!

Antworten

1 werner Sep 26 2020 at 22:56

Der VectorAssembler kann keine Spalten mit einem Leerzeichen oder einem Punkt im Spaltennamen verarbeiten. Eine andere Antwort von mir liefert einige technische Hintergrundinformationen, warum es nicht funktioniert.

Die einzige Möglichkeit besteht darin, die Spalten umzubenennen:

#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)