Apache spark 如何计算Spark数据帧中的行中值
我有以下格式的Spark数据帧Apache spark 如何计算Spark数据帧中的行中值,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我有以下格式的Spark数据帧 df=spark.createDataFrame([(1,2,3),(1,4100),(20,30,50)],['a','b','c']) df.show() 输入: df = spark.createDataFrame([(1,2,3),(100,1,10),(30,20,50)],['a','b','c']) import numpy as np from pyspark.sql.functions import udf from pyspark.sql.
df=spark.createDataFrame([(1,2,3),(1,4100),(20,30,50)],['a','b','c'])
df.show()
输入:
df = spark.createDataFrame([(1,2,3),(100,1,10),(30,20,50)],['a','b','c'])
import numpy as np
from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType
def my_median(*args):
return float(np.median(list(args)))
udf_median = udf(my_median, DoubleType())
df.withColumn('median', udf_median('a','b','c')).show()
我想添加一个新的列“median”,作为“a”、“b”、“c”列的中位数。如何在PySpark中实现这一点
预期输出:
df = spark.createDataFrame([(1,2,3),(100,1,10),(30,20,50)],['a','b','c'])
import numpy as np
from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType
def my_median(*args):
return float(np.median(list(args)))
udf_median = udf(my_median, DoubleType())
df.withColumn('median', udf_median('a','b','c')).show()
我正在使用Spark 2.3.1使用
udf
定义一个用户定义的函数,然后使用withColumn
将指定的列添加到数据框中:
from numpy import median
from pyspark.sql.functions import col, udf
from pyspark.sql.types import IntegerType
def my_median(a, b, c):
return int(median([int(a),int(b),int(c)]))
udf_median = udf(my_median, IntegerType())
df_t = df.withColumn('median', udf_median(df['a'], df['b'], df['c']))
df_t.show()
没有内置函数,但您可以使用现有组件轻松编写一个 Spark<2.4中的
#用sort_数组替换array_sort
#感谢@RaphaelRoth指出这一点
从pyspark.sql.functions导入数组、数组\排序、楼层、列、大小
从pyspark.sql导入列
def百分位数(p,*args):
def列(c):
如果存在(c列):
返回c
elif isinstance(c,str):
返回列(c)
其他:
raise TypeError(“args应该str或Column,got{}.”格式(type(c)))
xs=array_sort(数组(*[col_ux)表示参数中的x]))
n=尺寸(xs)
h=(n-1)*p
i=地板(h)铸件(“int”)
x0,x1=xs[i],xs[i+1]
返回x0+(h-i)*(x1-x0)
用法示例:
df.withColumn(“中值”,百分位数(0.5,*df.columns)).show()
+---+---+---+------+
|a | b | c |中位数|
+---+---+---+------+
| 1| 2| 3| 2.0|
| 1| 4|100| 4.0|
| 20| 30| 50| 30.0|
+---+---+---+------+
同样的事情也可以在Scala中完成:
import org.apache.spark.sql.functions_
导入org.apache.spark.sql.Column
def百分位数(p:Double,args:Column*)={
val xs=array_sort(数组(args:*))
val n=大小(xs)
val h=(n-1)*p
val i=地板(h)铸件(“内部”)
val(x0,x1)=(xs(i),xs(i+1))
x0+(h-i)*(x1-x0)
}
val df=Seq((1,2,3),(1,4100),(20,30,50)).toDF(“a”,“b”,“c”)
df.带列(“中位数”,百分位数(0.5,$“a”,“$“b”,“$“c”))。显示
+---+---+---+------+
|a | b | c |中位数|
+---+---+---+------+
| 1| 2| 3| 2.0|
| 1| 4|100| 4.0|
| 20| 30| 50| 30.0|
+---+---+---+------+
<>在<强> Python 中,您也可以考虑向量化的UDF——一般来说,它可能比内置函数慢,但优于非矢量化<代码> UDF:
从pyspark.sql.functions导入pandas\u udf,PandasUDFType
从pyspark.sql.types导入DoubleType
作为pd进口熊猫
将numpy作为np导入
def/U百分位数(p=0.5):
assert 0我稍微修改了OmG的答案,使UDF对于“n”个列的数量而不是仅仅3个列是动态的
代码:
df = spark.createDataFrame([(1,2,3),(100,1,10),(30,20,50)],['a','b','c'])
import numpy as np
from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType
def my_median(*args):
return float(np.median(list(args)))
udf_median = udf(my_median, DoubleType())
df.withColumn('median', udf_median('a','b','c')).show()
输出:
df = spark.createDataFrame([(1,2,3),(100,1,10),(30,20,50)],['a','b','c'])
import numpy as np
from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType
def my_median(*args):
return float(np.median(list(args)))
udf_median = udf(my_median, DoubleType())
df.withColumn('median', udf_median('a','b','c')).show()
@RaphaelRoth别担心。仅供参考,我添加了Scala等效物。谢谢array\u sort
只是在spark 2.4中添加的,sort\u array
应该也能工作吧