Me pregunto cuál es la diferencia entre an RDD
y DataFrame
(Spark 2.0.0 DataFrame es un simple alias de tipo para Dataset[Row]
) en Apache Spark.
¿Puedes convertir uno a otro?
Me pregunto cuál es la diferencia entre an RDD
y DataFrame
(Spark 2.0.0 DataFrame es un simple alias de tipo para Dataset[Row]
) en Apache Spark.
¿Puedes convertir uno a otro?
Respuestas:
A DataFrame
se define bien con una búsqueda en Google de "definición de marco de datos":
Un marco de datos es una tabla, o estructura tipo matriz bidimensional, en la que cada columna contiene medidas en una variable, y cada fila contiene un caso.
Entonces, a DataFrame
tiene metadatos adicionales debido a su formato tabular, que permite a Spark ejecutar ciertas optimizaciones en la consulta finalizada.
Una RDD
, por otra parte, es simplemente un R esilient D istributed D ataset que es más de un blackbox de datos que no pueden ser optimizados como las operaciones que se pueden realizar en contra de ella, no son tan limitados.
Sin embargo, puede pasar de un DataFrame a una RDD
vía su rdd
método, y puede pasar de una RDD
a una DataFrame
(si el RDD está en formato tabular) a través del toDF
método
En general , se recomienda utilizar un DataFrame
cuando sea posible debido a la optimización de consulta incorporada.
Lo primero
DataFrame
fue evolucionado deSchemaRDD
.
Sí ... la conversión entre Dataframe
y RDD
es absolutamente posible.
A continuación hay algunos fragmentos de código de muestra.
df.rdd
es RDD[Row]
A continuación se presentan algunas opciones para crear un marco de datos.
1) yourrddOffrow.toDF
convierte a DataFrame
.
2) Uso createDataFrame
del contexto sql
val df = spark.createDataFrame(rddOfRow, schema)
donde el esquema puede ser de algunas de las opciones a continuación como se describe en una buena publicación SO.
De la clase de caso scala y la API de reflexión scalaimport org.apache.spark.sql.catalyst.ScalaReflection val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]
O usando
Encoders
import org.apache.spark.sql.Encoders val mySchema = Encoders.product[MyCaseClass].schema
como se describe en Schema también se puede crear usando
StructType
yStructField
val schema = new StructType() .add(StructField("id", StringType, true)) .add(StructField("col1", DoubleType, true)) .add(StructField("col2", DoubleType, true)) etc...
De hecho, ahora hay 3 API de Apache Spark.
RDD
API:La
RDD
API (conjunto de datos distribuidos resilientes) ha estado en Spark desde la versión 1.0.La
RDD
API proporciona muchos métodos de transformación, comomap
(),filter
() yreduce
() para realizar cálculos en los datos. Cada uno de estos métodos da como resultado una nuevaRDD
representación de los datos transformados. Sin embargo, estos métodos solo definen las operaciones a realizar y las transformaciones no se realizan hasta que se llama a un método de acción. Ejemplos de métodos de acción soncollect
() ysaveAsObjectFile
().
Ejemplo de RDD:
rdd.filter(_.age > 21) // transformation
.map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action
Ejemplo: filtro por atributo con RDD
rdd.filter(_.age > 21)
DataFrame
APISpark 1.3 introdujo una nueva
DataFrame
API como parte de la iniciativa Project Tungsten que busca mejorar el rendimiento y la escalabilidad de Spark. LaDataFrame
API introduce el concepto de un esquema para describir los datos, lo que le permite a Spark administrar el esquema y solo pasar datos entre nodos, de una manera mucho más eficiente que usar la serialización de Java.La
DataFrame
API es radicalmente diferente de laRDD
API porque es una API para construir un plan de consulta relacional que el optimizador Catalyst de Spark puede ejecutar. La API es natural para los desarrolladores que están familiarizados con la creación de planes de consulta.
Ejemplo de estilo SQL:
df.filter("age > 21");
Limitaciones: Debido a que el código se refiere a los atributos de datos por nombre, el compilador no puede detectar ningún error. Si los nombres de los atributos son incorrectos, el error solo se detectará en tiempo de ejecución, cuando se crea el plan de consulta.
Otra desventaja de la DataFrame
API es que está muy centrada en la escala y, aunque admite Java, la compatibilidad es limitada.
Por ejemplo, al crear DataFrame
un objeto existente RDD
de Java, el optimizador Catalyst de Spark no puede inferir el esquema y supone que cualquier objeto en el DataFrame implementa la scala.Product
interfaz. Scala case class
funciona de la caja porque implementan esta interfaz.
Dataset
APILa
Dataset
API, lanzada como una vista previa de API en Spark 1.6, tiene como objetivo proporcionar lo mejor de ambos mundos; el estilo de programación familiar orientado a objetos y la seguridad de tipo de tiempo de compilación de laRDD
API pero con los beneficios de rendimiento del optimizador de consultas Catalyst. Los conjuntos de datos también usan el mismo mecanismo eficiente de almacenamiento fuera del montón que laDataFrame
API.Cuando se trata de serializar datos, la
Dataset
API tiene el concepto de codificadores que traducen entre representaciones JVM (objetos) y el formato binario interno de Spark. Spark tiene codificadores incorporados que son muy avanzados en el sentido de que generan código de bytes para interactuar con datos fuera del montón y proporcionar acceso bajo demanda a atributos individuales sin tener que deserializar un objeto completo. Spark aún no proporciona una API para implementar codificadores personalizados, pero eso está planeado para una versión futura.Además, la
Dataset
API está diseñada para funcionar igualmente bien con Java y Scala. Cuando se trabaja con objetos Java, es importante que sean totalmente compatibles con bean.
Ejemplo de Dataset
estilo SQL API:
dataset.filter(_.age < 21);
Las evaluaciones dif. entre DataFrame
& DataSet
:
Flujo a nivel catalista. (Desmitificación de la presentación de DataFrame y Dataset de la cumbre de chispas)
Lecturas adicionales ... artículo de databricks - Un cuento de tres API de Apache Spark: RDD vs DataFrames y Datasets
df.filter("age > 21");
esto puede evaluarse / analizarse solo en tiempo de ejecución. desde su cadena. En caso de conjuntos de datos, los conjuntos de datos son compatibles con Beans. entonces la edad es propiedad del frijol. Si la propiedad age no está en tu bean, entonces llegarás a saber temprano en el tiempo de compilación (ie dataset.filter(_.age < 21);
). El error de análisis puede renombrarse como Errores de evaluación.
Apache Spark proporciona tres tipos de API
Aquí está la comparación de API entre RDD, Dataframe y Dataset.
La abstracción principal que proporciona Spark es un conjunto de datos distribuido resiliente (RDD), que es una colección de elementos particionados en los nodos del clúster que se pueden operar en paralelo.
Colección distribuida:
RDD utiliza operaciones MapReduce, que es ampliamente adoptada para procesar y generar grandes conjuntos de datos con un algoritmo paralelo y distribuido en un clúster. Permite a los usuarios escribir cálculos paralelos, utilizando un conjunto de operadores de alto nivel, sin tener que preocuparse por la distribución del trabajo y la tolerancia a fallas.
Inmutable: RDDs compuestos de una colección de registros que están particionados. Una partición es una unidad básica de paralelismo en un RDD, y cada partición es una división lógica de datos que es inmutable y creada a través de algunas transformaciones en particiones existentes. La inmutabilidad ayuda a lograr consistencia en los cálculos.
Tolerante a fallas: en el caso de que perdamos parte de RDD, podemos reproducir la transformación en esa partición en linaje para lograr el mismo cálculo, en lugar de hacer la replicación de datos en múltiples nodos. Esta característica es el mayor beneficio de RDD porque ahorra muchos esfuerzos en la gestión y replicación de datos y, por lo tanto, logra cálculos más rápidos.
Evaluaciones diferidas : todas las transformaciones en Spark son diferidas, ya que no calculan sus resultados de inmediato. En cambio, solo recuerdan las transformaciones aplicadas a algún conjunto de datos base. Las transformaciones solo se calculan cuando una acción requiere que se devuelva un resultado al programa del controlador.
Transformaciones funcionales: los RDD admiten dos tipos de operaciones: transformaciones, que crean un nuevo conjunto de datos a partir de una existente, y acciones, que devuelven un valor al programa del controlador después de ejecutar un cálculo en el conjunto de datos.
Formatos de procesamiento de datos:
puede procesar de manera fácil y eficiente los datos estructurados y no estructurados.
Lenguajes de programación compatibles: la
API RDD está disponible en Java, Scala, Python y R.
Sin motor de optimización incorporado: cuando se trabaja con datos estructurados, los RDD no pueden aprovechar las ventajas de los optimizadores avanzados de Spark, incluido el optimizador de catalizador y el motor de ejecución de tungsteno. Los desarrolladores deben optimizar cada RDD en función de sus atributos.
Manejo de datos estructurados: a diferencia del Dataframe y los conjuntos de datos, los RDD no infieren el esquema de los datos ingeridos y requieren que el usuario los especifique.
Spark introdujo Dataframes en la versión Spark 1.3. El marco de datos supera los desafíos clave que tenían los RDD.
Un DataFrame es una colección distribuida de datos organizados en columnas con nombre. Es conceptualmente equivalente a una tabla en una base de datos relacional o un Marco de datos R / Python. Junto con Dataframe, Spark también introdujo el optimizador de catalizador, que aprovecha las características avanzadas de programación para construir un optimizador de consultas extensible.
Colección distribuida de objetos de fila: un DataFrame es una colección distribuida de datos organizados en columnas con nombre. Es conceptualmente equivalente a una tabla en una base de datos relacional, pero con optimizaciones más completas.
Procesamiento de datos: procesamiento de formatos de datos estructurados y no estructurados (Avro, CSV, búsqueda elástica y Cassandra) y sistemas de almacenamiento (HDFS, tablas HIVE, MySQL, etc.). Puede leer y escribir desde todos estos diversos orígenes de datos.
Optimización mediante el catalizador optimizador: alimenta tanto las consultas SQL como la API de DataFrame. El marco de datos utiliza el marco de transformación del árbol catalizador en cuatro fases,
1.Analyzing a logical plan to resolve references
2.Logical plan optimization
3.Physical planning
4.Code generation to compile parts of the query to Java bytecode.
Compatibilidad de Hive: con Spark SQL, puede ejecutar consultas de Hive sin modificar en sus almacenes de Hive existentes. Reutiliza la interfaz de Hive y MetaStore y le brinda total compatibilidad con los datos, consultas y UDF existentes de Hive.
Tungsteno: Tungsteno proporciona un backend de ejecución física que gestiona explícitamente la memoria y genera dinámicamente bytecode para la evaluación de expresiones.
Lenguajes de programación compatibles: la
API de marco de datos está disponible en Java, Scala, Python y R.
Ejemplo:
case class Person(name : String , age : Int)
val dataframe = sqlContext.read.json("people.json")
dataframe.filter("salary > 10000").show
=> throws Exception : cannot resolve 'salary' given input age , name
Esto es un desafío especialmente cuando trabajas con varios pasos de transformación y agregación.
Ejemplo:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
personDF.rdd // returns RDD[Row] , does not returns RDD[Person]
Dataset API es una extensión de DataFrames que proporciona una interfaz de programación orientada a objetos y segura de tipos. Es una colección inmutable fuertemente tipada de objetos que se asignan a un esquema relacional.
En el núcleo del conjunto de datos, API es un nuevo concepto llamado codificador, que es responsable de la conversión entre objetos JVM y representación tabular. La representación tabular se almacena utilizando el formato binario de tungsteno interno de Spark, lo que permite operaciones en datos serializados y una mejor utilización de la memoria. Spark 1.6 viene con soporte para generar automáticamente codificadores para una amplia variedad de tipos, incluidos los tipos primitivos (por ejemplo, String, Integer, Long), clases de caso Scala y Java Beans.
Proporciona lo mejor de RDD y Dataframe: RDD (programación funcional, tipo seguro), DataFrame (modelo relacional, optimización de consultas, ejecución de tungsteno, clasificación y barajado)
Codificadores: con el uso de codificadores, es fácil convertir cualquier objeto JVM en un conjunto de datos, lo que permite a los usuarios trabajar con datos estructurados y no estructurados a diferencia de Dataframe.
Lenguajes de programación compatibles: la API de conjuntos de datos actualmente solo está disponible en Scala y Java. Python y R actualmente no son compatibles con la versión 1.6. El soporte de Python está programado para la versión 2.0.
Tipo de seguridad: Datasets API proporciona seguridad en tiempo de compilación que no estaba disponible en Dataframes. En el siguiente ejemplo, podemos ver cómo Dataset puede operar en objetos de dominio con funciones lambda de compilación.
Ejemplo:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
val ds:Dataset[Person] = personDF.as[Person]
ds.filter(p => p.age > 25)
ds.filter(p => p.salary > 25)
// error : value salary is not a member of person
ds.rdd // returns RDD[Person]
Ejemplo:
ds.select(col("name").as[String], $"age".as[Int]).collect()
No hay soporte para Python y R: a partir de la versión 1.6, los conjuntos de datos solo admiten Scala y Java. El soporte de Python se introducirá en Spark 2.0.
La API de conjuntos de datos ofrece varias ventajas sobre la RDD existente y la API de trama de datos con una mejor seguridad de tipo y programación funcional. Con el desafío de los requisitos de conversión de tipo en la API, aún no sería la seguridad de tipo requerida y hará que su código sea frágil.
Dataset
no es LINQ y la expresión lambda no puede interpretarse como árboles de expresión. Por lo tanto, hay recuadros negros y pierde casi todos los beneficios del optimizador (si no todos). Solo un pequeño subconjunto de posibles inconvenientes: Spark 2.0 Dataset vs DataFrame . Además, solo para repetir algo que dije varias veces: en general, la verificación de tipos de extremo a extremo no es posible con Dataset
API. Las uniones son solo el ejemplo más destacado.
RDD
RDD
es una colección de elementos tolerantes a fallas que pueden operarse en paralelo.
DataFrame
DataFrame
es un conjunto de datos organizado en columnas con nombre. Es conceptualmente equivalente a una tabla en una base de datos relacional o un marco de datos en R / Python, pero con optimizaciones más ricas bajo el capó .
Dataset
Dataset
es una colección distribuida de datos. Dataset es una nueva interfaz agregada en Spark 1.6 que proporciona los beneficios de los RDD (tipeo fuerte, capacidad de usar potentes funciones lambda) con los beneficios del motor de ejecución optimizado de Spark SQL .
Nota:
El conjunto de datos de filas (
Dataset[Row]
) en Scala / Java a menudo se denominará marcos de datos .
Nice comparison of all of them with a code snippet.
P: ¿Puede convertir uno a otro como RDD a DataFrame o viceversa?
1. RDD
a DataFrame
con.toDF()
val rowsRdd: RDD[Row] = sc.parallelize(
Seq(
Row("first", 2.0, 7.0),
Row("second", 3.5, 2.5),
Row("third", 7.0, 5.9)
)
)
val df = spark.createDataFrame(rowsRdd).toDF("id", "val1", "val2")
df.show()
+------+----+----+
| id|val1|val2|
+------+----+----+
| first| 2.0| 7.0|
|second| 3.5| 2.5|
| third| 7.0| 5.9|
+------+----+----+
Más formas: Convierta un objeto RDD a Dataframe en Spark
2. DataFrame
/ DataSet
a RDD
con .rdd()
método
val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD
Porque DataFrame
está mal escrito y los desarrolladores no obtienen los beneficios del sistema de tipos. Por ejemplo, supongamos que desea leer algo de SQL y ejecutar alguna agregación en él:
val people = sqlContext.read.parquet("...")
val department = sqlContext.read.parquet("...")
people.filter("age > 30")
.join(department, people("deptId") === department("id"))
.groupBy(department("name"), "gender")
.agg(avg(people("salary")), max(people("age")))
Cuando dice people("deptId")
, no está recuperando un Int
, o un Long
, está recuperando un Column
objeto sobre el que necesita operar. En lenguajes con sistemas de tipo rico como Scala, terminas perdiendo toda la seguridad de tipos, lo que aumenta la cantidad de errores de tiempo de ejecución para cosas que se pueden descubrir en tiempo de compilación.
Por el contrario, DataSet[T]
está escrito. Cuando tu lo hagas:
val people: People = val people = sqlContext.read.parquet("...").as[People]
En realidad, está recuperando un People
objeto, donde deptId
es un tipo integral real y no un tipo de columna, aprovechando así el sistema de tipos.
A partir de Spark 2.0, las API DataFrame y DataSet estarán unificadas, donde DataFrame
habrá un alias de tipo DataSet[Row]
.
DataFrame
era evitar romper los cambios de API. De todos modos, solo quería señalarlo. Gracias por la edición y el voto de mi parte.
Simplemente RDD
es un componente central, pero DataFrame
es una API introducida en spark 1.30.
Colección de particiones de datos llamada RDD
. Estas RDD
deben seguir algunas propiedades tales como:
Aquí RDD
está estructurado o no estructurado.
DataFrame
es una API disponible en Scala, Java, Python y R. Permite procesar cualquier tipo de datos estructurados y semiestructurados. Para definir DataFrame
, se llama una colección de datos distribuidos organizados en columnas con nombre DataFrame
. Puede optimizar fácilmente RDDs
en DataFrame
. Puede procesar datos JSON, datos de parquet, datos HiveQL a la vez utilizando DataFrame
.
val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")
val sample_DF = sampleRDD.toDF()
Aquí Sample_DF considera como DataFrame
. sampleRDD
se llama (datos sin procesar) RDD
.
La mayoría de las respuestas son correctas solo quieren agregar un punto aquí
En Spark 2.0, las dos API (DataFrame + DataSet) se unificarán en una sola API.
"Unificación de DataFrame y Dataset: en Scala y Java, DataFrame y Dataset se han unificado, es decir, DataFrame es solo un alias de tipo para Dataset of Row. En Python y R, dada la falta de seguridad de tipos, DataFrame es la interfaz de programación principal".
Los conjuntos de datos son similares a los RDD, sin embargo, en lugar de utilizar la serialización Java o Kryo, utilizan un codificador especializado para serializar los objetos para procesarlos o transmitirlos a través de la red.
Spark SQL admite dos métodos diferentes para convertir RDD existentes en conjuntos de datos. El primer método usa la reflexión para inferir el esquema de un RDD que contiene tipos específicos de objetos. Este enfoque basado en la reflexión conduce a un código más conciso y funciona bien cuando ya conoce el esquema mientras escribe su aplicación Spark.
El segundo método para crear conjuntos de datos es a través de una interfaz programática que le permite construir un esquema y luego aplicarlo a un RDD existente. Si bien este método es más detallado, le permite construir conjuntos de datos cuando las columnas y sus tipos no se conocen hasta el tiempo de ejecución.
Aquí puede encontrar RDD para la respuesta de conversación del marco de datos
Un DataFrame es equivalente a una tabla en RDBMS y también se puede manipular de manera similar a las colecciones distribuidas "nativas" en los RDD. A diferencia de los RDD, los marcos de datos realizan un seguimiento del esquema y admiten varias operaciones relacionales que conducen a una ejecución más optimizada. Cada objeto DataFrame representa un plan lógico, pero debido a su naturaleza "perezosa" no se ejecuta ninguna ejecución hasta que el usuario llama a una "operación de salida" específica.
¡Espero que ayude!
Un Dataframe es un RDD de objetos Row, cada uno representando un registro. Un Dataframe también conoce el esquema (es decir, los campos de datos) de sus filas. Si bien los Dataframes se parecen a los RDD normales, internamente almacenan datos de una manera más eficiente, aprovechando su esquema. Además, proporcionan nuevas operaciones que no están disponibles en los RDD, como la capacidad de ejecutar consultas SQL. Los marcos de datos se pueden crear a partir de fuentes de datos externas, de los resultados de consultas o de RDD regulares.
Referencia: Zaharia M., et al. Learning Spark (O'Reilly, 2015)
Spark RDD (resilient distributed dataset)
:
RDD es la API principal de abstracción de datos y está disponible desde la primera versión de Spark (Spark 1.0). Es una API de nivel inferior para manipular la recopilación distribuida de datos. Las API RDD exponen algunos métodos extremadamente útiles que se pueden usar para obtener un control muy estricto sobre la estructura de datos físicos subyacente. Es una colección inmutable (solo lectura) de datos particionados distribuidos en diferentes máquinas. RDD permite el cálculo en memoria en grandes grupos para acelerar el procesamiento de grandes datos de una manera tolerante a fallas. Para habilitar la tolerancia a fallas, RDD usa DAG (Gráfico Acíclico Dirigido) que consiste en un conjunto de vértices y bordes. Los vértices y bordes en DAG representan el RDD y la operación que se aplicará en ese RDD respectivamente. Las transformaciones definidas en RDD son perezosas y se ejecutan solo cuando se llama a una acción
Spark DataFrame
:
Spark 1.3 introdujo dos nuevas API de abstracción de datos: DataFrame y DataSet. Las API de DataFrame organizan los datos en columnas con nombre como una tabla en la base de datos relacional. Permite a los programadores definir esquemas en una colección distribuida de datos. Cada fila en un DataFrame es de fila de tipo de objeto. Al igual que una tabla SQL, cada columna debe tener el mismo número de filas en un DataFrame. En resumen, DataFrame es un plan vagamente evaluado que especifica las operaciones que deben realizarse en la recopilación distribuida de datos. DataFrame también es una colección inmutable.
Spark DataSet
:
Como una extensión de las API de DataFrame, Spark 1.3 también introdujo las API de DataSet que proporcionan una interfaz de programación estrictamente tipada y orientada a objetos en Spark. Es una recopilación de datos distribuidos inmutable y segura. Al igual que DataFrame, las API de DataSet también usan el motor Catalyst para permitir la optimización de la ejecución. DataSet es una extensión de las API de DataFrame.
Other Differences
-
Un DataFrame es un RDD que tiene un esquema. Puede pensarlo como una tabla de base de datos relacional, ya que cada columna tiene un nombre y un tipo conocido. El poder de DataFrames proviene del hecho de que, cuando crea un DataFrame a partir de un conjunto de datos estructurado (Json, Parquet ..), Spark puede inferir un esquema haciendo un pase sobre todo el conjunto de datos (Json, Parquet ..) siendo cargado Luego, al calcular el plan de ejecución, Spark puede usar el esquema y hacer optimizaciones de cálculo sustancialmente mejores. Tenga en cuenta que DataFrame se llamaba SchemaRDD antes de Spark v1.3.0
Spark RDD -
Un RDD significa conjuntos de datos distribuidos resistentes. Es una colección de registros de partición de solo lectura. RDD es la estructura de datos fundamental de Spark. Permite a un programador realizar cálculos en memoria en grandes grupos de manera tolerante a fallas. Por lo tanto, acelerar la tarea.
Spark Dataframe -
A diferencia de un RDD, los datos se organizan en columnas con nombre. Por ejemplo, una tabla en una base de datos relacional. Es una colección de datos distribuida inmutable. DataFrame en Spark permite a los desarrolladores imponer una estructura en una colección distribuida de datos, lo que permite una abstracción de nivel superior.
Conjunto de datos de chispa -
Los conjuntos de datos en Apache Spark son una extensión de la API DataFrame que proporciona una interfaz de programación orientada a objetos y segura de tipos. El conjunto de datos aprovecha el optimizador Catalyst de Spark al exponer expresiones y campos de datos a un planificador de consultas.
Toda gran respuesta y el uso de cada API tiene algo de compensación. El conjunto de datos está diseñado para ser súper API para resolver muchos problemas, pero muchas veces RDD aún funciona mejor si comprende sus datos y si el algoritmo de procesamiento está optimizado para hacer muchas cosas en un solo paso a datos grandes, entonces RDD parece ser la mejor opción.
La agregación que usa la API del conjunto de datos todavía consume memoria y mejorará con el tiempo.