簡體   English   中英

計算Spark DataFrame中分組數據的標准偏差

[英]Calculate the standard deviation of grouped data in a Spark DataFrame

我有從csv獲取並轉換為DataFrame的用戶日志,以便利用SparkSQL查詢功能。 一個用戶每小時會創建多個條目,我想為每個用戶收集一些基本統計信息; 實際上,它只是用戶實例的數量,平均值以及眾多列的標准偏差。 通過使用groupBy($“ user”)和帶有SparkSQL函數的聚合器來計數和平均,我能夠快速獲取均值和計數信息:

val meanData = selectedData.groupBy($"user").agg(count($"logOn"),
avg($"transaction"), avg($"submit"), avg($"submitsPerHour"), avg($"replies"),
avg($"repliesPerHour"), avg($"duration"))

但是,我似乎找不到一種同樣優雅的方法來計算標准偏差。 到目前為止,我只能通過映射字符串,雙對並使用StatCounter()。stdev實用工具來計算它:

val stdevduration = duration.groupByKey().mapValues(value =>
org.apache.spark.util.StatCounter(value).stdev)

但是,這將返回一個RDD,我想嘗試將其全部保留在DataFrame中,以便對返回的數據進行進一步的查詢。

Spark 1.6+

您可以使用stddev_pop計算總體標准偏差,並使用stddev / stddev_samp計算無偏樣本標准偏差:

import org.apache.spark.sql.functions.{stddev_samp, stddev_pop}

selectedData.groupBy($"user").agg(stdev_pop($"duration"))

Spark 1.5及以下原始答案 ):

不是那么漂亮和有偏見(與describe返回的值相同),而是使用公式:

維基百科

您可以執行以下操作:

import org.apache.spark.sql.functions.sqrt

selectedData
    .groupBy($"user")
    .agg((sqrt(
        avg($"duration" * $"duration") -
        avg($"duration") * avg($"duration")
     )).alias("duration_sd"))

您當然可以創建一個減少混亂的函數:

import org.apache.spark.sql.Column
def mySd(col: Column): Column = {
    sqrt(avg(col * col) - avg(col) * avg(col))
}

df.groupBy($"user").agg(mySd($"duration").alias("duration_sd"))

也可以使用Hive UDF:

df.registerTempTable("df")
sqlContext.sql("""SELECT user, stddev(duration)
                  FROM df
                  GROUP BY user""")

圖片來源: https//en.wikipedia.org/wiki/Standard_deviation

接受的代碼有錯別字(如MRez指出的),因此無法編譯。 以下代碼段可以正常工作並經過測試。

對於Spark 2.0+

import org.apache.spark.sql.functions._
val _avg_std = df.groupBy("user").agg(
        avg(col("duration").alias("avg")),
        stddev(col("duration").alias("stdev")),
        stddev_pop(col("duration").alias("stdev_pop")),
        stddev_samp(col("duration").alias("stdev_samp"))
        )

暫無
暫無

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

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