Pyspark:将具有嵌套结构的数组转换为字符串

Oma*_*r14 4 python sql apache-spark pyspark spark-dataframe

我有pyspark数据框,其中包含名为Filters的列:“ array>”

我想将数据帧保存在csv文件中,为此,我需要将数组转换为字符串类型。

我尝试将其强制转换为:DF.Filters.tostring()DF.Filters.cast(StringType()),但两种解决方案均会在“过滤器”列中为每一行生成错误消息:

org.apache.spark.sql.catalyst.expressions.UnsafeArrayData@56234c19

代码如下

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 
|  32103    | org.apache.spark.sql.catalyst.expressions.UnsafeArrayData@d9e517ce
|  218056   | org.apache.spark.sql.catalyst.expressions.UnsafeArrayData@3c744494
Run Code Online (Sandbox Code Playgroud)

样本JSON数据:

{"ClientNum":"abc123","Filters":[{"Op":"foo","Type":"bar","Val":"baz"}]}
Run Code Online (Sandbox Code Playgroud)

谢谢 !!

Vzz*_*arr 8

对于我来说,Pyspark 函数to_json()完成了这项工作。

与简单转换为 String 相比,它的一个优点是它还保留了“结构键”(而不仅仅是“结构值”)。因此,对于报告的示例,我会有类似的内容:

[{"Op":"foo","Type":"bar","Val":"baz"}]
Run Code Online (Sandbox Code Playgroud)

这对我来说更有用,因为我必须将结果写入 Postgres 表。在这种格式中,我可以轻松地使用 Postgres 中支持的 JSON 函数


Gar*_*n S 5

我创建了一个样本JSON数据集来匹配该模式:

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

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

+---------+------------------------------------------------------------------+
|ClientNum|Filters                                                           |
+---------+------------------------------------------------------------------+
|abc123   |org.apache.spark.sql.catalyst.expressions.UnsafeArrayData@60fca57e|
+---------+------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

使用explode()函数可以最佳化您的问题,该函数可以展平数组,然后使用星号扩展表示法:

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

使其成为由逗号分隔的单列字符串:

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

爆炸阵列参考:在Spark中展平行

“结构”类型的星形扩展参考:如何在spark数据框中展平结构?