簡體   English   中英

如何使用Apache Spark Scala獲取大型CSV / RDD [Array [double]]中所有列的直方圖?

[英]How to get Histogram of all columns in a large CSV / RDD[Array[double]] using Apache Spark Scala?

我正在嘗試使用Spark Scala計算CSV文件中所有列的直方圖。

我發現DoubleRDDFunctions支持直方圖。 所以我編碼如下所示獲取所有列的直方圖。

  1. 獲取列數
  2. 創建每列的RDD[double]並使用DoubleRDDFunctions計算每個RDD直方圖

     var columnIndexArray = Array.tabulate(rdd.first().length) (_ * 1) val histogramData = columnIndexArray.map(columns => { rdd.map(lines => lines(columns)).histogram(6) }) 

這是一個好方法嗎? 誰能提出一些更好的方法來解決這個問題?

提前致謝。

不是更好,但替代方法是將RDD轉換為DataFrame並使用histogram_numeric UDF。

示例數據:

import scala.util.Random
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions.{callUDF, lit, col}
import org.apache.spark.sql.Row
import org.apache.spark.sql.hive.HiveContext

val sqlContext = new HiveContext(sc)

Random.setSeed(1)

val ncol = 5

val rdd = sc.parallelize((1 to 1000).map(
  _ => Row.fromSeq(Array.fill(ncol)(Random.nextDouble))
))

val schema = StructType(
  (1 to ncol).map(i => StructField(s"x$i", DoubleType, false)))

val df = sqlContext.createDataFrame(rdd, schema)
df.registerTempTable("df")

查詢:

val nBuckets = 3
val columns = df.columns.map(
  c => callUDF("histogram_numeric", col(c), lit(nBuckets)).alias(c))
val histograms = df.select(columns: _*)

histograms.printSchema

// root
//  |-- x1: array (nullable = true)
//  |    |-- element: struct (containsNull = true)
//  |    |    |-- x: double (nullable = true)
//  |    |    |-- y: double (nullable = true)
//  |-- x2: array (nullable = true)
//  |    |-- element: struct (containsNull = true)
//  |    |    |-- x: double (nullable = true)
//  |    |    |-- y: double (nullable = true)
//  |-- x3: array (nullable = true)
//  |    |-- element: struct (containsNull = true)
//  |    |    |-- x: double (nullable = true)
//  |    |    |-- y: double (nullable = true)
//  |-- x4: array (nullable = true)
//  |    |-- element: struct (containsNull = true)
//  |    |    |-- x: double (nullable = true)
//  |    |    |-- y: double (nullable = true)
//  |-- x5: array (nullable = true)
//  |    |-- element: struct (containsNull = true)
//  |    |    |-- x: double (nullable = true)
//  |    |    |-- y: double (nullable = true)

histograms.select($"x1").collect()

// Array([WrappedArray([0.16874313309969038,334.0],
//   [0.513382068667877,345.0], [0.8421388886903808,321.0])])

(scala api)轉換, countByValue應該做你想要的

所以例如為RDD中的第一列生成直方圖數據:

val histCol1 = RDD.map(record => record.col_1).countByValue()

在上面的表達式中, record只引用RDD中的數據行,它是具有字段col_1的案例類的實例

所以histCol1將返回一個哈希表(Scala Map),其中鍵是第1列(col_1)中的唯一值,值顯然是每個唯一值的頻率

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM