【问题标题】:Best approach to divide the single column into multiple columns Dataframe Spark Scala将单列划分为多列的最佳方法 Dataframe Spark Scala
【发布时间】:2019-12-13 16:48:04
【问题描述】:

我有一个数据框,它有一列,值与一些分隔符连接,现在我想分成多列,最多可以接近 1000-2000 列,记录数可以是 6000 万左右。我正在努力寻找最好的方法来做到这一点,所以性能不会受到影响。

我有以下方法,但是,如果有更好的方法来实现这一点,有人可以建议吗?

val df = Seq(("1|2|3|4|5|6|7|8|9")).toDF("data")

val df2 = df1.withColumn("_tmp", split(col("data"), "\\|"))

df2.select(   $"_tmp".getItem(0).as("col1"),
      $"_tmp".getItem(1).as("col2"),
      $"_tmp".getItem(2).as("col3"),
      $"_tmp".getItem(3).as("col4")).drop("_tmp")

提前非常感谢。

【问题讨论】:

  • 在我头上,因为你只提到了一列。为什么在加载数据本身时不能使用相同的逻辑来拆分数据,并且这些数据将作为列读取,并且您可以为相同的定义架构。
  • 我正在从hbase表中读取数据,所以每个数据集都作为一个列限定符存储在hbase表中,无论哪种方式都会出现性能问题,所以试图找到最好的方法。

标签: scala dataframe apache-spark apache-spark-sql


【解决方案1】:

如果您的数据存储在磁盘上,您可以简单地按照以下方式读取它:

val df = spark.read.format("csv").option("delimiter", "|").load(<path_to_data>)

如果文件没有标题(我假设在您的情况下没有标题)并且您不喜欢默认列命名 (_c0, _c1, ... , _cN),您可以简单地通过以下方式重命名它:

val newColumnNames = (1 to df.columns.size).map("col" + _)
val df2 = df.toDF(newColumnNames: _*)

如果您的数据存储在内存中,例如 String s,并且所有分隔的数据点属于同一类型,您可以首先将数据并行化为 RDD,然后通过推断将其转换为 DataFrame架构:

import org.apache.spark.sql.types._
import org.apache.spark.sql.Row

val data = s.split("\\|")
val schema = StructType((1 to data.size).map(c => StructField("col" + c, StringType, false)))
val dataRDD = spark.sparkContext.makeRDD(Seq(org.apache.spark.sql.Row(data: _*)))
val df = spark.sqlContext.createDataFrame(dataRDD, schema)

【讨论】:

    【解决方案2】:

    如果您知道列数,您可以稍微自动化一下:

    val df = Seq(("1|2|3|4|5|6|7|8|9")).toDF("data")
    
    val ncols = 9
    val selectExpr = (0 to ncols-1).map(i => $"tmp"(i).as(s"col${i+1}"))
    df
      .withColumn("tmp", split(col("data"), "\\|"))
      .select(selectExpr:_*)
      .show()
    

    给予:

    +----+----+----+----+----+----+----+----+----+
    |col1|col2|col3|col4|col5|col6|col7|col8|col9|
    +----+----+----+----+----+----+----+----+----+
    |   1|   2|   3|   4|   5|   6|   7|   8|   9|
    +----+----+----+----+----+----+----+----+----+
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      • 2020-04-24
      • 2016-03-20
      • 1970-01-01
      • 2017-01-07
      相关资源
      最近更新 更多