簡體   English   中英

將數據框架構從窄模式更改為全模式

[英]Change dataframe schema from narrow one to full

假設我有以下數據集:

+--------+--------+--------+--------+
| field1 | field2 | field3 | field4 |
+--------+--------+--------+--------+
|      0 |      1 | 0.15   |  2.132 |
|      1 |      2 | 0.72   |   0.15 |
|      2 |     12 | error  |        |
|      3 |     75 | error  |        |
+--------+--------+--------+--------+

如您所見, field3可能包含double 精度string值。 這里唯一可能的string值是error 如果出現error值,則field4根本不包含任何值(事實上,在field3之后有15個字段,出於可讀性考慮,我省略了這些字段,因為它們適用相同的規則)

因此,我正在嘗試完成以下任務:

  1. 讀取具有窄模式的輸入(僅包含前三個字段的描述)
  2. 過濾錯誤
  3. 應用新模式,該模式包含所有字段

因此,閱讀如下所示:

val er_schema = 
  StructType(
    Array(
      StructField("field1", IntegerType, true),
      StructField("field2", IntegerType, true),
      StructField("field3", StringType, true)))

val c_schema = 
  StructType(
    Array(
      StructField("field1", IntegerType, true),
      StructField("field2", IntegerType, true),
      // StringType only for now, DoubleType would be used instead
      StructField("field3", StringType, true),
      StructField("field4", StringType, true)))

val raw = sc.read.schema(er_schema).csv(PATH)
val correctOnly = filterErr(raw)
ss.createDataframe(
  correctOnly,
  c_schema))

這段代碼帶有異常: java.lang.ArrayIndexOutOfBoundsException:3

據我了解,這是因為底層的RDD僅包含3個第一字段。

因此,這是一個問題:是否有可能使用縮小的(在減少字段數的意義上)架構,然后將數據幀轉換為普通的(包含所有字段的)架構?

編輯1:源文件為CSV格式,如下所示:

0,1,0.15,2.132
1,2,0.72,0.15
2,12,error
3,75,error

我想到的可能解決方案是使用RDD並在過濾錯誤行之后應用完整模式,但是我想知道是否有可能僅通過使用數據幀來完成

編輯2:結果是我想要的:

正確的一個:

+--------+--------+--------+--------+
| field1 | field2 | field3 | field4 |
+--------+--------+--------+--------+
|      0 |      1 | 0.15   |  2.132 |
|      1 |      2 | 0.72   |   0.15 |
+--------+--------+--------+--------+

具有正確的數據類型(字段field3field4為DoubleType)

編輯3:這里的主要問題是與field3列-它不僅可以包含double field3值,還可以包含strings 我想擺脫帶有string值的行,而只保留帶有雙精度值的行。 我嘗試使用兩種不同的模式,但是它不起作用。

您可以通過將mode設置為DROPMALFORMED來刪除不遵循指定架構的DROPMALFORMED 讀取數據時,請使用所需的數據框的架構:

val schema = StructType(Array(
  StructField("field1", IntegerType, true),
  StructField("field2", IntegerType, true),
  StructField("field3", DoubleType, true),
  StructField("field4", DoubleType, true)
))

然后讀取csv文件:

val df = spark.read.
  .option("mode", "DROPMALFORMED")
  .schema(schema)
  .csv("/path/to/file")

這樣,所有沒有正確數據類型或錯誤行數的行都將被丟棄。

暫無
暫無

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

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