Saya ingin membuat DataFrame
dengan skema tertentu di Scala. Saya telah mencoba menggunakan JSON read (maksud saya membaca file kosong) tetapi menurut saya itu bukan praktik terbaik.
Saya ingin membuat DataFrame
dengan skema tertentu di Scala. Saya telah mencoba menggunakan JSON read (maksud saya membaca file kosong) tetapi menurut saya itu bukan praktik terbaik.
Jawaban:
Mari kita asumsikan Anda menginginkan bingkai data dengan skema berikut:
root
|-- k: string (nullable = true)
|-- v: integer (nullable = false)
Anda cukup menentukan skema untuk bingkai data dan menggunakan kosong RDD[Row]
:
import org.apache.spark.sql.types.{
StructType, StructField, StringType, IntegerType}
import org.apache.spark.sql.Row
val schema = StructType(
StructField("k", StringType, true) ::
StructField("v", IntegerType, false) :: Nil)
// Spark < 2.0
// sqlContext.createDataFrame(sc.emptyRDD[Row], schema)
spark.createDataFrame(sc.emptyRDD[Row], schema)
Setara PySpark hampir identik:
from pyspark.sql.types import StructType, StructField, IntegerType, StringType
schema = StructType([
StructField("k", StringType(), True), StructField("v", IntegerType(), False)
])
# or df = sc.parallelize([]).toDF(schema)
# Spark < 2.0
# sqlContext.createDataFrame([], schema)
df = spark.createDataFrame([], schema)
Menggunakan encoder implisit (hanya Scala) dengan Product
tipe seperti Tuple
:
import spark.implicits._
Seq.empty[(String, Int)].toDF("k", "v")
atau kelas kasus:
case class KV(k: String, v: Int)
Seq.empty[KV].toDF
atau
spark.emptyDataset[KV].toDF
Mulai Spark 2.0.0, Anda dapat melakukan hal berikut.
Mari tentukan Person
kelas kasus:
scala> case class Person(id: Int, name: String)
defined class Person
Impor spark
SparkSession implisit Encoders
:
scala> import spark.implicits._
import spark.implicits._
Dan gunakan SparkSession untuk membuat kosong Dataset[Person]
:
scala> spark.emptyDataset[Person]
res0: org.apache.spark.sql.Dataset[Person] = [id: int, name: string]
Anda juga dapat menggunakan Skema "DSL" (lihat Fungsi dukungan untuk DataFrames di org.apache.spark.sql.ColumnName ).
scala> val id = $"id".int
id: org.apache.spark.sql.types.StructField = StructField(id,IntegerType,true)
scala> val name = $"name".string
name: org.apache.spark.sql.types.StructField = StructField(name,StringType,true)
scala> import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructType
scala> val mySchema = StructType(id :: name :: Nil)
mySchema: org.apache.spark.sql.types.StructType = StructType(StructField(id,IntegerType,true), StructField(name,StringType,true))
scala> import org.apache.spark.sql.Row
import org.apache.spark.sql.Row
scala> val emptyDF = spark.createDataFrame(sc.emptyRDD[Row], mySchema)
emptyDF: org.apache.spark.sql.DataFrame = [id: int, name: string]
scala> emptyDF.printSchema
root
|-- id: integer (nullable = true)
|-- name: string (nullable = true)
spark.emptyDataset
modul saya tidak ada, Bagaimana cara menggunakannya? ada beberapa (benar) mirip dengan (tidak benar) val df = apache.spark.emptyDataset[RawData]
?
spark
adalah nilai yang Anda buat menggunakan SparkSession.builder
bukan bagian dari org.apache.spark
paket. Ada dua spark
nama yang digunakan. Ini adalah spark
Anda telah tersedia di spark-shell
luar kotak.
import scala.reflect.runtime.{universe => ru}
def createEmptyDataFrame[T: ru.TypeTag] =
hiveContext.createDataFrame(sc.emptyRDD[Row],
ScalaReflection.schemaFor(ru.typeTag[T].tpe).dataType.asInstanceOf[StructType]
)
case class RawData(id: String, firstname: String, lastname: String, age: Int)
val sourceDF = createEmptyDataFrame[RawData]
Di sini Anda dapat membuat skema menggunakan StructType dalam skala dan meneruskan Empty RDD sehingga Anda dapat membuat tabel kosong. Kode berikut untuk hal yang sama.
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql._
import org.apache.spark.sql.Row
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.IntegerType
import org.apache.spark.sql.types.BooleanType
import org.apache.spark.sql.types.LongType
import org.apache.spark.sql.types.StringType
//import org.apache.hadoop.hive.serde2.objectinspector.StructField
object EmptyTable extends App {
val conf = new SparkConf;
val sc = new SparkContext(conf)
//create sparksession object
val sparkSession = SparkSession.builder().enableHiveSupport().getOrCreate()
//Created schema for three columns
val schema = StructType(
StructField("Emp_ID", LongType, true) ::
StructField("Emp_Name", StringType, false) ::
StructField("Emp_Salary", LongType, false) :: Nil)
//Created Empty RDD
var dataRDD = sc.emptyRDD[Row]
//pass rdd and schema to create dataframe
val newDFSchema = sparkSession.createDataFrame(dataRDD, schema)
newDFSchema.createOrReplaceTempView("tempSchema")
sparkSession.sql("create table Finaltable AS select * from tempSchema")
}
Versi Java untuk membuat DataSet kosong:
public Dataset<Row> emptyDataSet(){
SparkSession spark = SparkSession.builder().appName("Simple Application")
.config("spark.master", "local").getOrCreate();
Dataset<Row> emptyDataSet = spark.createDataFrame(new ArrayList<>(), getSchema());
return emptyDataSet;
}
public StructType getSchema() {
String schemaString = "column1 column2 column3 column4 column5";
List<StructField> fields = new ArrayList<>();
StructField indexField = DataTypes.createStructField("column0", DataTypes.LongType, true);
fields.add(indexField);
for (String fieldName : schemaString.split(" ")) {
StructField field = DataTypes.createStructField(fieldName, DataTypes.StringType, true);
fields.add(field);
}
StructType schema = DataTypes.createStructType(fields);
return schema;
}
Berikut adalah solusi yang membuat dataframe kosong di pyspark 2.0.0 atau lebih.
from pyspark.sql import SQLContext
sc = spark.sparkContext
schema = StructType([StructField('col1', StringType(),False),StructField('col2', IntegerType(), True)])
sqlContext.createDataFrame(sc.emptyRDD(), schema)
Pada Spark 2.4.3
val df = SparkSession.builder().getOrCreate().emptyDataFrame