固定长度在火花鳞片中解析



我已经创建了数据框,输入就是这样:

   +-----------------------------------+
   |value                              |
   +-----------------------------------+
   |1   PRE123                    21   |
   |2   TEST                      32   |
   |7   XYZ                       .7   |
   +-----------------------------------+

并且,在以下元数据信息的基础上,我们需要拆分上述数据框架并创建一个新的数据框架,具有列名称ID,名称和类,并且在此JSON META数据中给出了启动和索引储据。

   {
    "columnName": "id",
    "start": 1,
    "end": 2
  },
  {
    "columnName": "name",
    "start": 5,
    "end": 10
  },
  {
    "columnName": "class",
    "start": 20,
    "end": 22
  }

输出:

  +---+------+-----+
  | id|  name|class|
  +---+------+-----+
  |  1|PRE123|   21|
  |  2|  TEST|   32|
  |  7|   XYZ|   .7|
  +---+------+-----+

用于加载DF,我创建了列表:

   list.+=(loadedDF.col("value").substr(fixedLength.getStart, (fixedLength.getEnd - fixedLength.getStart)).alias(fixedLength.getColumnName))

从此列表中,我创建了数据框

var df: DataFrame = loadedDF.select(list: _*)

需要了解从元数据创建数据框的更好的订单方法。由于创建的列表将将所有数据带到驱动程序节点。

如果我正确地理解了您的要求,您正在尝试从由任意数量的空格分隔的字符串中提取列。

这是一种具有子函数的解决方案:

val df = Seq(
  ("1   PRE123         21"),
  ("2   TEST           32"),
  ("7   XYZ            .7"))
.toDF("value")
val colMetadata = Map("id" -> (1,2), "name" -> (5,10), "class" -> (20,22))
val columns = colMetadata.map { case (cname, meta) => 
  val len = meta._2 - meta._1   
  $"value".substr(meta._1, len).as(cname)
}.toSeq
df.select(columns:_*).show

和一个通用解决方案当您没有使用拆分函数可用的列边界时:

import org.apache.spark.sql.functions.split
val df = Seq(
  ("1   PRE123         21"),
  ("2   TEST           32"),
  ("7   XYZ            .7"))
.toDF("value")
val colNames = Seq("id", "name", "class")
val columns = colNames.zipWithIndex.map { case (cname, idx) =>
      split($"value", "\s+").getItem(idx).as(cname)
}
df.select(columns:_*).show

输出:

+---+------+-----+
| id|  name|class|
+---+------+-----+
|  1|PRE123|   21|
|  2|  TEST|   32|
|  7|   XYZ|   .7|
+---+------+-----+

请注意,我将\s+用作分离器。这代表一个或多个空格

相关内容

  • 没有找到相关文章

最新更新