2017-04-11 83 views
1

我pyspark數據框和一個叫列過濾器: 「陣列>」Pyspark:投陣列嵌套結構來串

我要救我的csv文件數據框中,爲此我需要轉換數組到字符串類型。

我試着投它:DF.Filters.tostring()DF.Filters.cast(StringType()),但兩種方案產生的列過濾器的每一行的錯誤消息:

[email protected]19

的代碼如下

from pyspark.sql.types import StringType 

DF.printSchema() 

|-- ClientNum: string (nullable = true) 
|-- Filters: array (nullable = true) 
    |-- element: struct (containsNull = true) 
      |-- Op: string (nullable = true) 
      |-- Type: string (nullable = true) 
      |-- Val: string (nullable = true) 

DF_cast = DF.select ('ClientNum',DF.Filters.cast(StringType())) 

DF_cast.printSchema() 

|-- ClientNum: string (nullable = true) 
|-- Filters: string (nullable = true) 

DF_cast.show() 

| ClientNum | Filters 
|3 | [email protected]ce 
| 218056 | [email protected]3c744494 

樣品JSON數據:

{"ClientNum":"abc123","Filters":[{"Op":"foo","Type":"bar","Val":"baz"}]} 

謝謝!

+0

可以共享最少的代碼。 –

+0

你能改造前打印模式和顯示數據。轉換後也打印模式。 –

+0

模式似乎是正確的。 – Omar14

回答

1

我創建了一個示例JSON數據集相匹配的模式:

{"ClientNum":"abc123","Filters":[{"Op":"foo","Type":"bar","Val":"baz"}]} 

select(s.col("ClientNum"),s.col("Filters").cast(StringType)).show(false) 

+---------+------------------------------------------------------------------+ 
|ClientNum|Filters               | 
+---------+------------------------------------------------------------------+ 
|abc123 |[email protected]7e| 
+---------+------------------------------------------------------------------+ 

你的問題最好用這削弱了陣列的爆炸()函數解決,那麼星號擴展表示法:

s.selectExpr("explode(Filters) AS structCol").selectExpr("structCol.*").show() 
+---+----+---+ 
| Op|Type|Val| 
+---+----+---+ 
|foo| bar|baz| 
+---+----+---+ 

使單列字符串由通信隔開如:

s.selectExpr("explode(Filters) AS structCol").select(F.expr("concat_ws(',', structCol.*)").alias("single_col")).show() 
+-----------+ 
| single_col| 
+-----------+ 
|foo,bar,baz| 
+-----------+ 

爆炸陣列參考:Flattening Rows in Spark

星展開 「結構」 式的參考:How to flatten a struct in a spark dataframe?

+0

這會在頂部結構,而不是所有列的內容作爲字符串 – alfredox

+0

@alfredox更新,提高單列版本一列列。 – Garren

-1

你可以試試這個:

DF = DF.withColumn('Filters', DF.Filters.cast("string")) 
+0

我試過了,同樣的結果:[email protected] – Omar14

+0

我說你必須運行UDF,你可以應用一些邏輯數組轉換爲字符串,然後選擇新的列 –