You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark DataFrame使用CountVectorizerModel时String类型不匹配错误

问题根因

你对报错的判断准确,CountVectorizerModel 要求输入列类型为 Array[String](字符串数组),而你传入的 ocean_proximity 是普通单值字符串类型,因此触发了类型校验失败。

修复方案

方法1:适配CountVectorizerModel的最小修改方案

只需要提前把单值字符串列转换为单元素字符串数组即可,修改代码如下:
首先引入数组构造函数:

import org.apache.spark.sql.functions.array

调整转换逻辑:

// 将单String列包装为单元素数组列
val dfWithArrayCol = dfRaw.withColumn("ocean_proximity_arr", array(col("ocean_proximity")))

val cvmDF = new CountVectorizerModel(tags)
  .setInputCol("ocean_proximity_arr") // 改用转换后的数组列作为输入
  .setOutputCol("sparseFeatures")
  .transform(dfWithArrayCol)

注意:你后续生成列别名的写法存在错误,s"$distinctOceanProximities(i)" 会把整个数组转为字符串后拼接(i)后缀,需要修改为 ${distinctOceanProximities(i)} 才能正确取对应下标的分类值作为列名。

方法2:更适配单值分类列的推荐方案

你的需求是对单值分类列做独热编码后转稠密向量,用 StringIndexer + OneHotEncoder 的组合比CountVectorizer更适配该场景,不需要提前收集全量分类值、也不需要手动构造CountVectorizerModel的tags参数,代码更稳定:

import org.apache.spark.ml.feature.StringIndexer
import org.apache.spark.ml.feature.OneHotEncoder
import org.apache.spark.ml.linalg.Vector
import org.apache.spark.sql.functions.udf

// 1. 字符串分类值映射为数值索引
val indexer = new StringIndexer()
  .setInputCol("ocean_proximity")
  .setOutputCol("ocean_proximity_idx")
  .fit(dfRaw)

// 2. 数值索引转为独热稀疏向量
val encoder = new OneHotEncoder()
  .setInputCol("ocean_proximity_idx")
  .setOutputCol("sparseFeatures")
  .setDropLast(false) // 保留所有分类维度,不会丢弃最后一类

// 3. 稀疏向量转数组
val vecToArray = udf((v: Vector) => v.toArray)
val distinctVals = indexer.labels // 直接取训练好的分类标签,顺序和独热向量维度一一对应

// 4. 执行转换拆分多列
val dfTransformed = encoder.transform(indexer.transform(dfRaw))
  .withColumn("features_arr", vecToArray(col("sparseFeatures")))

val exprs = (0 until distinctVals.length).map(i => col("features_arr")(i).alias(distinctVals(i)))
val finalDF = dfTransformed.select(exprs:_*)
finalDF.show()

内容的提问来源于stack exchange,提问作者joesan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 18:06:05