কিভাবে rdd অবজেক্টটি স্পার্কে ডেটাফ্রেমে রূপান্তর করা যায়


139

আমি কীভাবে org.apache.spark.rdd.RDD[org.apache.spark.sql.Row]কোনও আরডিডি ( ) কে ডেটাফ্রেমে রূপান্তর করতে পারি org.apache.spark.sql.DataFrame। আমি একটি ডেটাফ্রেমকে আরডিডি ব্যবহার করে রূপান্তর করেছি .rdd। এটি প্রক্রিয়া করার পরে আমি এটি ডেটা ফ্রেমে ফিরে চাই। কিভাবে আমি এটি করতে পারব ?


উত্তর:


88

SqlContextএকটি createDataFrameপদ্ধতি তৈরি করে যা একটি DataFrameপ্রদত্ত একটি তৈরি করে RDD। আমি ধারণা করি এর মধ্যে একটি আপনার প্রসঙ্গে কাজ করবে।

উদাহরণ স্বরূপ:

def createDataFrame(rowRDD: RDD[Row], schema: StructType): DataFrame

প্রদত্ত স্কিমা ব্যবহার করে সজ্জিত একটি আরডিডি থেকে একটি ডেটা ফ্রেম তৈরি করে।


93

এই কোডটি স্পার্ক ২.x থেকে স্কেলা ২.১১ এর সাথে পুরোপুরি কাজ করে

প্রয়োজনীয় ক্লাস আমদানি করুন

import org.apache.spark.sql.{Row, SparkSession}
import org.apache.spark.sql.types.{DoubleType, StringType, StructField, StructType}

SparkSessionঅবজেক্ট তৈরি করুন এবং এটি এখানেspark

val spark: SparkSession = SparkSession.builder.master("local").getOrCreate
val sc = spark.sparkContext // Just used to create test RDDs

আসুন RDDএটি তৈরি করতে একটিDataFrame

val rdd = sc.parallelize(
  Seq(
    ("first", Array(2.0, 1.0, 2.1, 5.4)),
    ("test", Array(1.5, 0.5, 0.9, 3.7)),
    ("choose", Array(8.0, 2.9, 9.1, 2.5))
  )
)

পদ্ধতি 1

ব্যবহার SparkSession.createDataFrame(RDD obj)

val dfWithoutSchema = spark.createDataFrame(rdd)

dfWithoutSchema.show()
+------+--------------------+
|    _1|                  _2|
+------+--------------------+
| first|[2.0, 1.0, 2.1, 5.4]|
|  test|[1.5, 0.5, 0.9, 3.7]|
|choose|[8.0, 2.9, 9.1, 2.5]|
+------+--------------------+

পদ্ধতি 2

SparkSession.createDataFrame(RDD obj)কলামের নাম ব্যবহার এবং নির্দিষ্টকরণ।

val dfWithSchema = spark.createDataFrame(rdd).toDF("id", "vals")

dfWithSchema.show()
+------+--------------------+
|    id|                vals|
+------+--------------------+
| first|[2.0, 1.0, 2.1, 5.4]|
|  test|[1.5, 0.5, 0.9, 3.7]|
|choose|[8.0, 2.9, 9.1, 2.5]|
+------+--------------------+

পদ্ধতি 3 (প্রশ্নের আসল উত্তর)

এই পথে ইনপুট rddটাইপ হওয়া উচিত RDD[Row]

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 schema = new StructType()
  .add(StructField("id", StringType, true))
  .add(StructField("val1", DoubleType, true))
  .add(StructField("val2", DoubleType, true))

এখন উভয় আবেদন rowsRddএবং schemaকরতেcreateDataFrame()

val df = spark.createDataFrame(rowsRdd, schema)

df.show()
+------+----+----+
|    id|val1|val2|
+------+----+----+
| first| 2.0| 7.0|
|second| 3.5| 2.5|
| third| 7.0| 5.9|
+------+----+----+

2
বোধগম্যভাবে ক্রিয়েডাটাফ্রেম ব্যবহারের বিভিন্ন উপায় দেখানোর জন্য আপনাকে ধন্যবাদ
ভ্যাটসুগ

তৃতীয় পদ্ধতিটি ডেটা ইটগুলিতে সহায়ক কারণ অন্যরা কাজ করছে না এবং ত্রুটি দিচ্ছে
নরেন্দ্র মারু

67

আপনার আরডিডি [সারিতে] ধরে নিলে আরডিডি বলা হয়, আপনি এটি ব্যবহার করতে পারেন:

val sqlContext = new SQLContext(sc) 
import sqlContext.implicits._
rdd.toDF()

26
আমি মনে করি এটি আরডিডি [সারি] এর পক্ষে কাজ করে না। আমি কি কিছু মিস করছি?
ড্যানিয়েল ডি পাওলা

4
যেহেতু স্পার্ক ২.০ এসকিউএল কনটেক্সট স্পার্কসেশন দ্বারা প্রতিস্থাপন করা হয়েছে, তবে ক্লাসটি পশ্চাদগম্য সামঞ্জস্যের জন্য স্কেলডক (কোডাল বেস ) রাখা হয়েছে। এটি ব্যবহার করে হ্রাসের সতর্কতা নিক্ষেপ করে।
টমাসকাজেমেকাস

18

দ্রষ্টব্য: এই উত্তরটি এখানে মূলত পোস্ট করা হয়েছিল

আমি এই উত্তরটি পোস্ট করছি কারণ আমি অন্যান্য উত্তরগুলিতে পাইনি এমন উপলভ্য বিকল্পগুলি সম্পর্কে অতিরিক্ত বিশদটি ভাগ করতে চাই


সারিগুলির আরডিডি থেকে একটি ডেটা ফ্রেম তৈরি করতে দুটি প্রধান বিকল্প রয়েছে:

1) ইতিমধ্যে চিহ্নিত হিসাবে, আপনি ব্যবহার করতে পারেন toDF()যা দ্বারা আমদানি করা যেতে পারে import sqlContext.implicits._। যাইহোক, এই পদ্ধতিটি কেবল নিম্নলিখিত ধরণের আরডিডিগুলির জন্য কাজ করে:

  • RDD[Int]
  • RDD[Long]
  • RDD[String]
  • RDD[T <: scala.Product]

(সূত্র: Scaladoc এর SQLContext.implicitsঅবজেক্ট)

সর্বশেষ স্বাক্ষরটির অর্থ হ'ল এটি টিউপসগুলির একটি আরডিডি বা কেস ক্লাসগুলির একটি আরডিডি (কারণ টিপলস এবং কেস ক্লাসের সাবক্লাস হয় scala.Product) এর জন্য কাজ করতে পারে।

সুতরাং, কোনওটির জন্য এই পদ্ধতির ব্যবহার RDD[Row]করতে আপনাকে এটিকে মানচিত্র করতে হবে RDD[T <: scala.Product]। নিম্নলিখিত কোড স্নিপেটের মতো কাস্টম কেস ক্লাসে বা টুপলে প্রতিটি সারি ম্যাপিংয়ের মাধ্যমে এটি করা যেতে পারে:

val df = rdd.map({ 
  case Row(val1: String, ..., valN: Long) => (val1, ..., valN)
}).toDF("col1_name", ..., "colN_name")

অথবা

case class MyClass(val1: String, ..., valN: Long = 0L)
val df = rdd.map({ 
  case Row(val1: String, ..., valN: Long) => MyClass(val1, ..., valN)
}).toDF("col1_name", ..., "colN_name")

এই পদ্ধতির প্রধান ত্রুটি (আমার মতে) হ'ল আপনাকে মানচিত্রে ফাংশন, কলাম অনুসারে কলামে ফলাফল ডেটা ফ্রেমের স্কিমাটি স্পষ্টভাবে সেট করতে হবে। আপনি যদি আগে থেকে স্কিমাটি না জানেন তবে এটি অগ্রগতি সম্পন্ন হতে পারে তবে জিনিসগুলি সেখানে কিছুটা অগোছালো হতে পারে। সুতরাং, বিকল্পভাবে, অন্য বিকল্প আছে:


2) আপনি createDataFrame(rowRDD: RDD[Row], schema: StructType)গ্রহণযোগ্য উত্তর হিসাবে ব্যবহার করতে পারেন , যা এসকিউএল কনটেক্সট অবজেক্টে উপলব্ধ। পুরানো ডেটাফ্রেমের আরডিডি রূপান্তর করার উদাহরণ:

val rdd = oldDF.rdd
val newDF = oldDF.sqlContext.createDataFrame(rdd, oldDF.schema)

মনে রাখবেন যে কোনও স্কিমা কলাম সুস্পষ্টভাবে সেট করার দরকার নেই। আমরা পুরানো ডিএফ এর স্কিমাটি পুনরায় ব্যবহার করি, যা শ্রেণিবদ্ধ StructTypeএবং সহজেই বাড়ানো যেতে পারে। তবে, কখনও কখনও এই পদ্ধতির পক্ষে সম্ভব হয় না এবং কিছু ক্ষেত্রে প্রথমটির চেয়ে কম দক্ষ হতে পারে।


বিশদ জন্য ধন্যবাদimport sqlContext.implicits.
javadba

ভবিষ্যতে, দয়া করে একাধিক প্রশ্নের একই উত্তর পোস্ট করবেন না। যদি প্রশ্নগুলি সদৃশ হয় তবে একটি ভাল উত্তর পোস্ট করুন, তারপরে অন্য প্রশ্নটিকে নকল হিসাবে বন্ধ করতে ভোট বা পতাকা দিন। যদি প্রশ্নটি সদৃশ না হয় তবে আপনার প্রশ্নের উত্তরগুলি শিখুন। আমি কিভাবে একটি ভাল উত্তর লিখতে হবে দেখুন ?

15

ধরুন আপনার একটি রয়েছে DataFrameএবং আপনি ক্ষেত্রের ডেটাতে রূপান্তর করে কিছু পরিবর্তন করতে চান RDD[Row]

val aRdd = aDF.map(x=>Row(x.getAs[Long]("id"),x.getAs[List[String]]("role").head))

ফিরে রূপান্তর করতে DataFrameথেকে RDDআমরা সংজ্ঞায়িত করতে প্রয়োজন গঠন টাইপ এর RDD

যদি ডেটাটাইপটি থাকে Long তবে এটি LongTypeকাঠামোর মতো হয়ে যাবে ।

তাহলে Stringতারপর StringTypeকাঠামো।

val aStruct = new StructType(Array(StructField("id",LongType,nullable = true),StructField("role",StringType,nullable = true)))

এখন আপনি আরডিডিটি তৈরিডাটা ফ্রেম পদ্ধতিটি ব্যবহার করে ডেটাফ্রেমে রূপান্তর করতে পারেন ।

val aNamedDF = sqlContext.createDataFrame(aRdd,aStruct)

7

আপনার তালিকাটি স্পার্ক আরডিডি তে রূপান্তর করার এবং তারপরে সেই স্পার্ক আরডিডিটিকে ডেটাফ্রেমে রূপান্তর করার একটি সহজ উদাহরণ।

দয়া করে মনে রাখবেন যে আমি নিম্নলিখিত কোডটি কার্যকর করতে স্পার্ক-শেলের স্কেল রিপ্লে ব্যবহার করেছি, এখানে এসসি স্পার্ককন্টেক্সটসের একটি উদাহরণ যা স্পার্ক শেল-এ স্পষ্টত উপলব্ধ। আশা করি এটি আপনার প্রশ্নের উত্তর দিয়েছে।

scala> val numList = List(1,2,3,4,5)
numList: List[Int] = List(1, 2, 3, 4, 5)

scala> val numRDD = sc.parallelize(numList)
numRDD: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[80] at parallelize at <console>:28

scala> val numDF = numRDD.toDF
numDF: org.apache.spark.sql.DataFrame = [_1: int]

scala> numDF.show
+---+
| _1|
+---+
|  1|
|  2|
|  3|
|  4|
|  5|
+---+

একটি মজাদার তথ্য: আপনার তালিকাটি ইনট (বা লং, স্ট্রিং, <: প্রোডাক্ট) এর পরিবর্তে ডাবল হলে এটি কাজ করা বন্ধ করে দেয়।
রিক মরিটজ


6

পদ্ধতি 1: (স্কেলা)

val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext.implicits._
val df_2 = sc.parallelize(Seq((1L, 3.0, "a"), (2L, -1.0, "b"), (3L, 0.0, "c"))).toDF("x", "y", "z")

পদ্ধতি 2: (স্কেলা)

case class temp(val1: String,val3 : Double) 

val rdd = sc.parallelize(Seq(
  Row("foo",  0.5), Row("bar",  0.0)
))
val rows = rdd.map({case Row(val1:String,val3:Double) => temp(val1,val3)}).toDF()
rows.show()

পদ্ধতি 1: (পাইথন)

from pyspark.sql import Row
l = [('Alice',2)]
Person = Row('name','age')
rdd = sc.parallelize(l)
person = rdd.map(lambda r:Person(*r))
df2 = sqlContext.createDataFrame(person)
df2.show()

পদ্ধতি 2: (পাইথন)

from pyspark.sql.types import * 
l = [('Alice',2)]
rdd = sc.parallelize(l)
schema =  StructType([StructField ("name" , StringType(), True) , 
StructField("age" , IntegerType(), True)]) 
df3 = sqlContext.createDataFrame(rdd, schema) 
df3.show()

সারি অবজেক্ট থেকে মানটি বের করে এবং তারপরে কেস ক্লাস প্রয়োগ করে আরডিডিটিকে ডিএফ-তে রূপান্তর করতে

val temp1 = attrib1.map{case Row ( key: Int ) => s"$key" }
val temp2 = attrib2.map{case Row ( key: Int) => s"$key" }

case class RLT (id: String, attrib_1 : String, attrib_2 : String)
import hiveContext.implicits._

val df = result.map{ s => RLT(s(0),s(1),s(2)) }.toDF

4

স্পার্কের নতুন সংস্করণগুলিতে (২.০+)

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
import org.apache.spark.sql._
import org.apache.spark.sql.types._

val spark = SparkSession
  .builder()
  .getOrCreate()
import spark.implicits._

val dfSchema = Seq("col1", "col2", "col3")
rdd.toDF(dfSchema: _*)

1
স্পার্কসেশনটি স্কেলকন্টেক্সট, হাইভ কনকেক্সট-এর কেবল একটি মোড়ক
আর্কিট

1
One needs to create a schema, and attach it to the Rdd.

ধরে নিচ্ছি ভাল স্পার্ক একটি স্পার্কসেশন.বিল্ডারের পণ্য ...

    import org.apache.spark._
    import org.apache.spark.sql._       
    import org.apache.spark.sql.types._

    /* Lets gin up some sample data:
     * As RDD's and dataframes can have columns of differing types, lets make our
     * sample data a three wide, two tall, rectangle of mixed types.
     * A column of Strings, a column of Longs, and a column of Doubules 
     */
    val arrayOfArrayOfAnys = Array.ofDim[Any](2,3)
    arrayOfArrayOfAnys(0)(0)="aString"
    arrayOfArrayOfAnys(0)(1)=0L
    arrayOfArrayOfAnys(0)(2)=3.14159
    arrayOfArrayOfAnys(1)(0)="bString"
    arrayOfArrayOfAnys(1)(1)=9876543210L
    arrayOfArrayOfAnys(1)(2)=2.71828

    /* The way to convert an anything which looks rectangular, 
     * (Array[Array[String]] or Array[Array[Any]] or Array[Row], ... ) into an RDD is to 
     * throw it into sparkContext.parallelize.
     * http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.SparkContext shows
     * the parallelize definition as 
     *     def parallelize[T](seq: Seq[T], numSlices: Int = defaultParallelism)
     * so in our case our ArrayOfArrayOfAnys is treated as a sequence of ArraysOfAnys.
     * Will leave the numSlices as the defaultParallelism, as I have no particular cause to change it. 
     */
    val rddOfArrayOfArrayOfAnys=spark.sparkContext.parallelize(arrayOfArrayOfAnys)

    /* We'll be using the sqlContext.createDataFrame to add a schema our RDD.
     * The RDD which goes into createDataFrame is an RDD[Row] which is not what we happen to have.
     * To convert anything one tall and several wide into a Row, one can use Row.fromSeq(thatThing.toSeq)
     * As we have an RDD[somethingWeDontWant], we can map each of the RDD rows into the desired Row type. 
     */     
    val rddOfRows=rddOfArrayOfArrayOfAnys.map(f=>
        Row.fromSeq(f.toSeq)
    )

    /* Now to construct our schema. This needs to be a StructType of 1 StructField per column in our dataframe.
     * https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.types.StructField shows the definition as
     *   case class StructField(name: String, dataType: DataType, nullable: Boolean = true, metadata: Metadata = Metadata.empty)
     * Will leave the two default values in place for each of the columns:
     *        nullability as true, 
     *        metadata as an empty Map[String,Any]
     *   
     */

    val schema = StructType(
        StructField("colOfStrings", StringType) ::
        StructField("colOfLongs"  , LongType  ) ::
        StructField("colOfDoubles", DoubleType) ::
        Nil
    )

    val df=spark.sqlContext.createDataFrame(rddOfRows,schema)
    /*
     *      +------------+----------+------------+
     *      |colOfStrings|colOfLongs|colOfDoubles|
     *      +------------+----------+------------+
     *      |     aString|         0|     3.14159|
     *      |     bString|9876543210|     2.71828|
     *      +------------+----------+------------+
    */ 
    df.show 

একই পদক্ষেপ, তবে কম ভ্যালার ঘোষণা সহ:

    val arrayOfArrayOfAnys=Array(
        Array("aString",0L         ,3.14159),
        Array("bString",9876543210L,2.71828)
    )

    val rddOfRows=spark.sparkContext.parallelize(arrayOfArrayOfAnys).map(f=>Row.fromSeq(f.toSeq))

    /* If one knows the datatypes, for instance from JDBC queries as to RDBC column metadata:
     * Consider constructing the schema from an Array[StructField].  This would allow looping over 
     * the columns, with a match statement applying the appropriate sql datatypes as the second
     *  StructField arguments.   
     */
    val sf=new Array[StructField](3)
    sf(0)=StructField("colOfStrings",StringType)
    sf(1)=StructField("colOfLongs"  ,LongType  )
    sf(2)=StructField("colOfDoubles",DoubleType)        
    val df=spark.sqlContext.createDataFrame(rddOfRows,StructType(sf.toList))
    df.show

1

আমি গণনা সমস্যা শব্দটি ব্যবহার করে সমাধানটি ব্যাখ্যা করার চেষ্টা করেছি । 1. sc ব্যবহার করে ফাইলটি পড়ুন

  1. শব্দ গণনা উত্পাদন
  2. ডিএফ তৈরির পদ্ধতি

    • rdd.toDF পদ্ধতি
    • rdd.toDF ( "শব্দ", "গণনা")
      • spark.createDataFrame (rdd, স্কিমা)

    স্পার্ক ব্যবহার করে ফাইল পড়ুন

    val rdd=sc.textFile("D://cca175/data/")  

    ডেটাফ্রেমে আরডিডি করুন

    ভাল df = sc.textFile ("ডি: // cca175 / তথ্য /")। টোডিএফ ("t1") df.show

    পদ্ধতি 1

    ডেটাফ্রেমে শব্দ গণনা আরডিডি তৈরি করুন

    val df=rdd.flatMap(x=>x.split(" ")).map(x=>(x,1)).reduceByKey((x,y)=>(x+y)).toDF("word","count")

    Method2

    আরডিডি থেকে ডেটাফ্রেম তৈরি করুন

    val df=spark.createDataFrame(wordRdd) 
    # with header   
    val df=spark.createDataFrame(wordRdd).toDF("word","count")  df.show

    Method3

    স্কিমা সংজ্ঞায়িত করুন

    org.apache.spark.sql.types._ আমদানি করুন

    ভাল স্কিমা = নতুন স্ট্রাক্টটাইপ ()। (StructField ( "শব্দ", StringType, সত্য)) যোগ করুন। যোগ (StructField ( "গণনা", StringType, সত্য))

    RowRDD তৈরি করুন

    import org.apache.spark.sql.Row
    val rowRdd=wordRdd.map(x=>(Row(x._1,x._2)))     

    আরডিডি থেকে স্কিমা দিয়ে ডেটাফ্রেম তৈরি করুন

    ভাল df = spark.createDataFrame (রোআরডিডি, স্কিমা)
    df.show


0

একটি অ্যারে [সারি] কে ডেটাফ্রেম বা ডেটাসেটে রূপান্তর করতে, নীচেরগুলি মার্জিতভাবে কাজ করে:

বলুন, তারপরে স্কিমা হ'ল স্ট্রাক্টটাইপ

val rows: Array[Row]=...
implicit val encoder = RowEncoder.apply(schema)
import spark.implicits._
rows.toDS
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.