Java Spark ML indexer无法解析带点的数据帧列名?
我有一个数据框,其中一列名为a.b。当我指定a.b作为a的输入列名时,AnalysisException会显示消息“无法解析给定输入列a.b的'a.b'。我正在使用Spark 1.6.0 我知道Spark的旧版本可能在列名中有点问题,但在更新的版本中,可以在Spark shell中的列名周围以及SQL查询中使用反引号。例如,这是另一个问题的解决方案。其中一些问题已报告,但在1.4.0中得到了解决 下面是一个简单的示例和stacktrace:Java Spark ML indexer无法解析带点的数据帧列名?,java,apache-spark,apache-spark-mllib,apache-spark-ml,Java,Apache Spark,Apache Spark Mllib,Apache Spark Ml,我有一个数据框,其中一列名为a.b。当我指定a.b作为a的输入列名时,AnalysisException会显示消息“无法解析给定输入列a.b的'a.b'。我正在使用Spark 1.6.0 我知道Spark的旧版本可能在列名中有点问题,但在更新的版本中,可以在Spark shell中的列名周围以及SQL查询中使用反引号。例如,这是另一个问题的解决方案。其中一些问题已报告,但在1.4.0中得到了解决 下面是一个简单的示例和stacktrace: 公共类SparkMLDotColumn{ 公共静态vo
公共类SparkMLDotColumn{
公共静态void main(字符串[]args){
//了解上下文
SparkConf conf=新的SparkConf()
.setMaster(“本地[*]”)
.setAppName(“测试”)
.set(“spark.ui.enabled”、“false”);//http://permalink.gmane.org/gmane.comp.lang.scala.spark.user/21385
JavaSparkContext sparkContext=新的JavaSparkContext(conf);
SQLContext SQLContext=新的SQLContext(sparkContext);
//使用名为“a.b”的单个字符串列创建架构
StructType架构=新StructType(新StructField[]{
DataTypes.createStructField(“a.b”,DataTypes.StringType,false)
});
//创建一个空的RDD和数据帧
JavaRDD rdd=sparkContext.parallelize(Collections.emptyList());
DataFrame df=sqlContext.createDataFrame(rdd,模式);
StringIndexer indexer=新的StringIndexer()
.setInputCol(“a.b”)
.setOutputCol(“a.b_指数”);
df=索引器。拟合(df)。变换(df);
}
}
现在,值得尝试使用倒引号列名的相同示例,因为我们得到了一些奇怪的结果。下面是一个具有相同模式的示例,但这次我们在框架中获得了数据。在尝试任何索引之前,我们将名为a.b
的列复制到名为a\u b
的列。这就需要使用backticks,而且它可以毫无问题地工作。然后,我们将尝试为a_b
列编制索引,这不会出现问题。然后,当我们尝试使用反勾号为a.b
列编制索引时,会发生一些非常奇怪的事情。我们没有得到错误,但也没有得到结果:
public class SparkMLDotColumn {
public static void main(String[] args) {
// Get the contexts
SparkConf conf = new SparkConf()
.setMaster("local[*]")
.setAppName("test")
.set("spark.ui.enabled", "false");
JavaSparkContext sparkContext = new JavaSparkContext(conf);
SQLContext sqlContext = new SQLContext(sparkContext);
// Create a schema with a single string column named "a.b"
StructType schema = new StructType(new StructField[] {
DataTypes.createStructField("a.b", DataTypes.StringType, false)
});
// Create an empty RDD and DataFrame
List<Row> rows = Arrays.asList(RowFactory.create("foo"), RowFactory.create("bar"));
JavaRDD<Row> rdd = sparkContext.parallelize(rows);
DataFrame df = sqlContext.createDataFrame(rdd, schema);
df = df.withColumn("a_b", df.col("`a.b`"));
StringIndexer indexer0 = new StringIndexer();
indexer0.setInputCol("a_b");
indexer0.setOutputCol("a_bIndex");
df = indexer0.fit(df).transform(df);
StringIndexer indexer1 = new StringIndexer();
indexer1.setInputCol("`a.b`");
indexer1.setOutputCol("abIndex");
df = indexer1.fit(df).transform(df);
df.show();
}
}
来自第一个示例的Stacktrace
线程“main”org.apache.spark.sql.AnalysisException中的异常:无法解析给定输入列a.b的“a.b”;
位于org.apache.spark.sql.catalyst.analysis.package$AnalysisErrorAt.failAnalysis(package.scala:42)
在org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$CheckAnalysis$1$$anonfun$apply$2.applyOrElse(CheckAnalysis.scala:60)
在org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$CheckAnalysis$1$$anonfun$apply$2.applyOrElse(CheckAnalysis.scala:57)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$1.apply(TreeNode.scala:319)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$1.apply(TreeNode.scala:319)
位于org.apache.spark.sql.catalyst.trees.CurrentOrigin$.withOrigin(TreeNode.scala:53)
位于org.apache.spark.sql.catalyst.trees.TreeNode.transformUp(TreeNode.scala:318)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$5.apply(TreeNode.scala:316)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$5.apply(TreeNode.scala:316)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$4.apply(TreeNode.scala:265)
在scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
位于scala.collection.Iterator$class.foreach(Iterator.scala:727)
位于scala.collection.AbstractIterator.foreach(迭代器.scala:1157)
在scala.collection.generic.growtable$class.$plus$plus$eq(growtable.scala:48)
在scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:103)
在scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:47)
在scala.collection.TraversableOnce$class.to处(TraversableOnce.scala:273)
在scala.collection.AbstractIterator.to(Iterator.scala:1157)
在scala.collection.TraversableOnce$class.toBuffer处(TraversableOnce.scala:265)
位于scala.collection.AbstractIterator.toBuffer(Iterator.scala:1157)
位于scala.collection.TraversableOnce$class.toArray(TraversableOnce.scala:252)
位于scala.collection.AbstractIterator.toArray(Iterator.scala:1157)
位于org.apache.spark.sql.catalyst.trees.TreeNode.transformChildren(TreeNode.scala:305)
位于org.apache.spark.sql.catalyst.trees.TreeNode.transformUp(TreeNode.scala:316)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$5.apply(TreeNode.scala:316)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$5.apply(TreeNode.scala:316)
位于org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$4.apply(TreeNode.scala:265)
在scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
位于scala.collection.Iterator$class.foreach(Iterator.scala:727)
位于scala.collection.AbstractIterator.foreach(迭代器.scala:1157)
在scala.collection.generic.growtable$class.$plus$plus$eq(growtable.scala:48)
在scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:103)
在scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:47)
在scala.collection.TraversableOnce$class.to处(TraversableOnce.scala:273)
在scala.collection.AbstractIterator.to(Iterator.scala:1157)
在scala.collection.TraversableOnce$class.toBuffer处(TraversableOnce.scala:265)
位于scala.collection.AbstractIterator.toBuffer(Iterator.scala:1157)
位于scala.collection.TraversableOnce$class.toArray(TraversableOnce.scala:252)
位于scala.collection.AbstractIterator.toArray(Iterator.scala:1157)
位于org.apache.spark.sql.catalyst.trees.TreeNode.transformChildren(TreeNode.scala:305)
位于org.apache.spark.sql.catalyst.trees.TreeNode.transformUp(TreeNode.scala:316)
在org.apache.spark.sql.catalyst.plans.Qu上
def validifyColumnnames[T](df : Dataset[T], spark : SparkSession) : DataFrame = {
val newColumnNames = ArrayBuffer[String]()
for(oldCol <- df.columns) {
newColumnNames += oldCol.replaceAll("\\.","") // append
}
val newColumnNamesB = spark.sparkContext.broadcast(newColumnNames.toArray)
df.toDF(newColumnNamesB.value : _*)
}