Metoda transformacji PySpark za pomocą Vector Assembler
Mam Spark DataFrame i chciałbym użyć Vector Assembler do utworzenia kolumny „funkcje”.
from pyspark.ml.feature import VectorAssembler
assembler = VectorAssembler(inputCols=sel_cols, outputCol='features')
transformed_data = assembler.transform(sdf)
sel_cols składa się z listy 150 pozycji typu string, która wygląda następująco:
['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',...]
A sdf.columns, składa się z 340 elementów i wygląda następująco:
['.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',...]
Otrzymuję ten błąd podczas stosowania transformed_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,...
Jak pokazano, „ASP.NET Core” jest zdecydowanie jedną z moich kolumn sdf.O ile rozumiem, przekazywanie sel_cols jako listy ciągów do inputCols VectorAssemblera powinno działać ... Naprawdę doceniłbym wszelkie spostrzeżenia, ponieważ nie pracowałem z Spark DF przed :)
Dziękuję Ci!
Odpowiedzi
Element VectorAssembler nie obsługuje kolumn ze spacją lub kropką w nazwie kolumny. Inna odpowiedź ode mnie dostarcza pewnych technicznych informacji, dlaczego to nie działa.
Jedyną opcją jest zmiana nazw kolumn:
#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)