ago*_*zed 5 csv scala apache-spark
我的 csv 文件中的每一行的结构如下:
u001, 2013-11, 0, 1, 2, ... , 99
Run Code Online (Sandbox Code Playgroud)
其中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)
Run Code Online (Sandbox Code Playgroud)
其中 dataVector 是Array[Int],并且所有 UID 和日期的dataVector长度都相同。我尝试了几种方法来解决这个问题,包括
使用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)
Run Code Online (Sandbox Code Playgroud)但这种方式效果不佳。对于我后来的数据集中数据列大于100,我认为手动创建包含dataVector整列的模式也很不方便。
直接加载没有schema的csv文件,使用incatenate multicolumn into single column的方法将数据的列连接在一起,但是schema结构是这样的
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)
Run Code Online (Sandbox Code Playgroud)这仍然与我需要的不同,我没有找到将这个结构转换为我需要的方法。所以我的问题是如何将 csv 文件加载到我需要的结构中?
加载它而不添加任何内容
val df = spark.read.csv(path)
Run Code Online (Sandbox Code Playgroud)
并选择:
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")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1681 次 |
| 最近记录: |