簡體   English   中英

觸發單個數據框轉換為兩個具有id且一對多關系的表

[英]spark a single dataframe convert to two tables with id and a relationship of one to many

數據源是一個csv:

name,companyName
shop1,com1
shop2,com1
shop3,com1
shop4,com2
shop5,com2
shop6,com3

我使用spark將其讀取到一個數據幀中,並希望以一對多的關系將其轉換為兩個數據幀,預期的輸出是兩個數據幀。 一種是companyDF:

companyId,companyName
1,com1
2,com2
3,com3

另一個是shopDF:

shopId, shopName,   shopCompanyId
1,shop1,1
2,shop2,1
3,shop3,1
4,shop4,2
5,shop5,2
6,shop6,3

這兩個數據框可以在shopDF.shopCompanyId = companyDF.companyId和getData上連接。我使用monotonically_increasing_id()生成ID,例如1 2 3 4.。或者有更好的方法

我已經寫了一些代碼來做到這一點,並工作

package delme
import com.qydata.fuyun.util.Utils;
import scala.reflect.api.materializeTypeTag
import java.io.BufferedWriter
import java.io.InputStream
import java.io.InputStreamReader
import java.io.FileInputStream
import java.io.BufferedReader
import scala.util.control.Exception.Finally
import java.io.IOException
import org.apache.spark.SparkConf
import org.apache.spark.sql._
import org.apache.spark.sql.functions._
object OneToMany {
  def main(args: Array[String]){ 
    var sparkConf = new SparkConf().setMaster("local[*]")
     val builder =  SparkSession.builder().config(sparkConf)//.enableHiveSupport()  
     val ss =  builder.getOrCreate()  
     val sc = ss.sparkContext
     import ss.implicits._
      var shopdf = ss.read.format("csv")
              .option("header", "true")
            .option("inferSchema", "true")
            .load("data/shops.csv") 
      val companydf=shopdf.select("companyName").distinct().withColumn("companyId", monotonically_increasing_id())
      companydf.show()
      shopdf=shopdf.join(companydf,shopdf.col("companyName")===companydf.col("companyName"),"left_outer").select("name", "companyName","companyId")
      shopdf.show()
  }
}

但是我覺得這很愚蠢,我只想處理一次,而不是“區別”和“聯接”,首先是String上的運算符效率可能很低,其次如果我有增量數據,我就不會處理例如,另一批數據是:

name,companyName
shop1a,com1
shop2a,com1
shop3a,com1
shop4a,com2
shop5a,com2
shop6a,com3
shop7,com4

我想將它們附加到舊表中(實際上,我之前將數據保存到配置單元表中),然后我不知道。 這里應將ID為4的新公司com4追加到公司表中,並將(13,shop7,4)追加到shop表中

那么如何將源轉換為兩個數據幀?

val df1=df.withColumn(“companyId”,dense_rank.over(Window.orderBy(“companyName”))).withColumn(“shopId”,row_number.over(Window.orderBy(“name”)))
val companydf = df1.select(“companyName”,”companyId”).dropDuplicates
val shopdf= df1.select(col(“name”).alias(“shopName”,col(“shopId”),col(“companyId”).alias(“shopCompanyId”))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM