如何使用指定的架构创建空DataFrame?

时间:2015-07-17 13:58:53

标签: scala apache-spark dataframe apache-spark-sql

我想在DataFrame上使用Scala中的指定架构进行创建。我曾尝试使用JSON读取(我的意思是阅读空文件),但我认为这不是最好的做法。

7 个答案:

答案 0 :(得分:97)

假设您需要具有以下架构的数据框:

root
 |-- k: string (nullable = true)
 |-- v: integer (nullable = false)

您只需为数据框定义架构并使用空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)

将隐式编码器(仅限Scala)与Product类型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

答案 1 :(得分:3)

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]

答案 2 :(得分:3)

在这里,您可以使用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")

}

答案 3 :(得分:1)

用于创建空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;
}

答案 4 :(得分:1)

这对测试很有帮助。

Seq.empty[String].toDF()

答案 5 :(得分:0)

自Spark 2.4.3起

val df = SparkSession.builder().getOrCreate().emptyDataFrame

答案 6 :(得分:0)

我有一个特殊要求,其中我已经有一个数据框,但在一定条件下,我必须返回一个空的数据框,因此我返回了df.limit(0)