Función personalizada de Spark SQL_Capítulo 5

1. Clasificación de funciones personalizadas
Similar a las funciones personalizadas en la colmena, spark también puede usar funciones personalizadas para implementar nuevas funciones.
Las funciones personalizadas en spark son las siguientes:
1. UDF (función definida por el usuario) ingresa
una línea, emite una línea
2.UDAF (función de agregación definida por el usuario) ingresa
varias líneas, emite una línea
3.UDTF (tabla definida por el usuario) Funciones de generación)
ingresa una línea, emite múltiples líneas
2. UDF personalizado
Requisitos El
formato de datos de udf.txt es el siguiente:

Hola
abc
estudio
pequeño

Utilice la función UDF personalizada para convertir cada fila de datos en un
valor de selección en mayúscula , smallToBig (valor) de la demostración del
código t_word :

def main (args: Array [String]): Unit = {
// 1, crear sparksession
val spark: SparkSession = SparkSession.builder (). master (“local [*]”). appName (“demo01”). getOrCreate ( )
// 2, crea sparkcontext
val sc: SparkContext = spark.sparkContext
// 3, lee los datos. Y opere
val ttRDD: RDD [String] = sc.textFile (“file: /// F: \ Chuanzhi Podcast \ Chuanzhi Professional College \ Second Semester \ 34 \ 05-Spark \ Data \ udf.txt”)
import spark.implicits._
val UDFDS: Conjunto de datos [String] = ttRDD.toDS ()
// Función personalizada
spark.udf.register (“toUpperAdd123”, (str: String) => {
// Procesar datos de acuerdo con las necesidades del negocio
str.toUpperCase + "123"
})
UDFDS.createOrReplaceTempView ("UDF")
// Llamar a la función
spark.sql ("SELECCIONAR valor, toUpperAdd123 (valor) como length_10 FROM UDF"). show ()
sc.stop ()
spark.stop ()
}

3. Requisitos personalizados de UDAF [comprender]
: el
contenido de datos de udaf.json es el siguiente

{"Nombre": "Michael", "salario": 3000}
{"nombre": "Andy", "salario": 4500}
{"nombre": "Justin", "salario": 3500}
{"nombre": "Berta", "salario": 4000}

Para obtener el salario promedio
● Herede el método UserDefinedAggregateFunction para reescribir la descripción
inputSchema: el tipo de datos de entrada
bufferSchema: el tipo de datos
que produce el resultado intermedio tipo de datos : el tipo de resultado final devuelto
determinista: para garantizar la coherencia,
inicialización generalmente verdadera : especifique la
actualización del valor inicial : cada Una pieza de datos participa en la operación para actualizar los resultados intermedios (la actualización es equivalente a la operación en cada partición)
fusionar: agregación global (agregar los resultados de cada partición)
evaluar: calcular el resultado final
● demostración de código:

object Udaf {
// Escribe un método para calcular el salario promedio
Clase SalaryAvg SalaryAvg extiende UserDefinedAggregateFunction {
// Tipo de entrada de datos
anular def inputSchema: StructType = {
StructType (StructField ("input", LongType) :: Nil)
}
// Resultado intermedio Tipo de
reemplazo de caché def bufferSchema: StructType = {
// suma total de caché
// número total de cachés totales
StructType (List (StructField ("sum", LongType), (StructField ("total", LongType)))
}
// Tipo de datos devueltos
override def dataType: DataType = {
DoubleType
}
// ¿Existe la misma salida verdadera
override def deterministic: Boolean = {
true
}
/ *
List (1,2,3,4,5) .reduce ((a, b) => a + b)
1 a = 1 b = 2
2 a = 3 b = 3
. A = B = 6. 3. 4
. 4 A = B = 10. 5
5 = 51 es A.
/
// inicialización de datos
la anulación de la initialize DEF (Tampón: MutableAggregationBuffer): Unidad = {
// para el almacenamiento de la cantidad total de
tampón (0) = 0L / / => a
// Para tiempos de almacenamiento
buffer (1) = 0L // => b
}
// rdd es una partición. Este método es para calcular los datos y el número de datos en una partición
/

{"nombre": "Michael" , "Salario": 3000}
{"nombre": "Andy", "salario": 4500}
{"nombre": "Justin", "salario": 3500}
{"nombre": "Berta", "salario": 4000}
/
override def update (buffer: MutableAggregationBuffer, input: Row): Unit = {
// Calcule la cantidad total de la subpartición
buffer (0) = buffer.getLong (0) + input.getLong (0)
// Calcule la subpartición El número total de
buffer (1) = buffer.getLong (1) +1
}
// Resumen de la cantidad total y tiempos totales en todas las particiones
anular def merge (buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
// Cantidad total de todas las particiones
buffer1 (0) = buffer1.getLong (0) + buffer2.getLong (0)
// Número total de veces de todas las particiones
buffer1 (1) = buffer1.getLong (1) + buffer2.getLong (1)
}
// Encuentre el promedio final
// Calcule el salario promedio
// Cantidad total / Número total
anulado def evaluación (buffer: Fila): Cualquiera = {
buffer.getLong (0) .toDouble / buffer.getLong (1) .toDouble
}
}
def main (args: Array [String]): Unit = {
// 1, crear sparksession
val spark: SparkSession = SparkSession.builder (). master ("local [
]"). appName (“demo01”). getOrCreate ()
val JsonDatas: DataFrame = spark.read.json (“file: /// F: \ Chuanzhi Podcast \ Chuanzhi Professional College \ Second Semestre \ 34 \ 05-Spark \ Information \ udaf.json ")
JsonDatas.createOrReplaceTempView ("UDAFTable")
// Proceso de registro
UDAF función spark.udf.register ("SalaryAvg", nuevo SalaryAvg)
// El nombre del algoritmo para calcular el salario promedio es SalaryAvg
spark.sql ("seleccione SalaryAvg (salario) de UDAFTable" ) .show ()
spark.sql ("seleccione promedio (salario) de UDAFTable"). show ()
spark.stop ()
}
}

238 artículos originales publicados · elogiados 429 · 250,000 visitas

Supongo que te gusta

Origin blog.csdn.net/qq_45765882/article/details/105561548
Recomendado
Clasificación