如何使用Array [Int]将csv文件加载到Spark DataFrame中

时间:2017-12-15 02:26:59

标签: scala csv apache-spark

我的csv文件中的每一行都是这样构建的:

u001, 2013-11, 0, 1, 2, ... , 99

其中 u001 2013-11 是UID和日期,从 0 99 的数字是数据值。我想在此结构中将此csv文件加载到Spark DataFrame中:

+-------+-------------+-----------------+
|    uid|         date|       dataVector|
+-------+-------------+-----------------+
|   u001|      2013-11|  [0,1,...,98,99]|
|   u002|      2013-11| [1,2,...,99,100]|
+-------+-------------+-----------------+

root
 |-- uid: string (nullable = true)
 |-- date: string (nullable = true)
 |-- dataVecotr: array (nullable = true)
 |    |-- element: integer (containsNull = true)

其中dataVector是 Array [Int] dataVector 长度对于所有UID和日期都是相同的。 我已经尝试了几种方法来解决这个问题,包括

  1. 使用shema

    val attributes = Array("uid", "date", "dataVector)
    val schema = StructType(
    StructField(attributes(0), StringType, true) ::
    StructField(attributes(1), StringType, true) ::
    StructField(attributes(2), ArrayType(IntegerType), true) :: 
    Nil)
    
  2. 但这种方式效果不佳。由于我以后的数据集中的数据列大于100,我认为手动创建包含整个dataVector列的模式也很不方便。

    1. 直接加载没有架构的csv文件,并使用concatenate multiple columns into single columns中的方法将数据列连接在一起,但架构结构就像

       root
        |-- uid: string (nullable = true)
        |-- date: string (nullable = true)
        |-- dataVector: struct (nullable = true)
        |    |-- _c3: string (containsNull = true)
        |    |-- _c4: string (containsNull = true)
        .
        .
        .
        |    |-- _c101: string (containsNull = true)
      
    2. 这仍然与我需要的不同,我没有找到将这个结构转换成我需要的方法的方法。 所以我的问题是如何将csv文件加载到我需要的结构中?

1 个答案:

答案 0 :(得分:2)

加载它而不添加任何内容

val df = spark.read.csv(path)

并选择:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.Column

// Combine data into array
val dataVector: Column = array(
  df.columns.drop(2).map(col): _*  // Skip first 2 columns
).cast("array<int>")  // Cast to the required type
val cols: Array[Column] = df.columns.take(2).map(col) :+ dataVector

df.select(cols: _*).toDF("uid", "date", "dataVector")