DataFrame
Scalaでスキーマを指定して作成したい。私はJSON読み取り(つまり空のファイルを読み取ることを意味します)を使用しようとしましたが、それがベストプラクティスではないと思います。
DataFrame
Scalaでスキーマを指定して作成したい。私はJSON読み取り(つまり空のファイルを読み取ることを意味します)を使用しようとしましたが、それがベストプラクティスではないと思います。
回答:
次のスキーマのデータフレームが必要だとしましょう。
root
|-- k: string (nullable = true)
|-- v: integer (nullable = false)
データフレームのスキーマを定義し、emptyを使用するだけです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)
PySparkの同等の機能はほとんど同じです。
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)
次のProduct
ようなタイプの暗黙的なエンコーダー(Scalaのみ)の使用Tuple
:
import spark.implicits._
Seq.empty[(String, Int)].toDF("k", "v")
またはケースクラス:
case class KV(k: String, v: Int)
Seq.empty[KV].toDF
または
spark.emptyDataset[KV].toDF
Spark 2.0.0以降では、次のことができます。
Person
ケースクラスを定義しましょう:
scala> case class Person(id: Int, name: String)
defined class Person
spark
暗黙的なSparkSessionのインポートEncoders
:
scala> import spark.implicits._
import spark.implicits._
そして、SparkSessionを使用して空を作成しますDataset[Person]
。
scala> spark.emptyDataset[Person]
res0: org.apache.spark.sql.Dataset[Person] = [id: int, name: string]
また、(参照スキーマの「DSL」を使用することができますデータフレームのサポート機能をに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
私のモジュールに存在しないと言っていますが、どのように使用しますか?(正しくない)に似た(正しい)いくつかがありますかval df = apache.spark.emptyDataset[RawData]
?
spark
は、パッケージのSparkSession.builder
一部ではなく使用して作成する値ですorg.apache.spark
。2つのspark
名前が使用されています。それは、箱から出してすぐにspark
使用できるものですspark-shell
。
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]
ここでは、ScalaでStructTypeを使用してスキーマを作成し、Empty RDDを渡すことができるため、空のテーブルを作成できます。次のコードは同じです。
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")
}
空のDataSetを作成するJavaバージョン:
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;
}
Spark 2.4.3以降
val df = SparkSession.builder().getOrCreate().emptyDataFrame