【问题标题】:Spark - convert JSON array object to array of stringSpark - 将 JSON 数组对象转换为字符串数组
【发布时间】:2020-06-17 17:51:10
【问题描述】:

作为我的数据框的一部分,其中一列具有以下方式的数据

[{"text":"Tea"},{"text":"GoldenGlobes"}]

我想将其转换为字符串数组。

[“茶”、“金球奖”]

有人请告诉我,如何做到这一点?

【问题讨论】:

  • 你可以使用from_json(),用ArrayType()创建一个schema,并选择text命名的字段。 .使用方法见here示例

标签: apache-spark dataframe pyspark apache-spark-sql


【解决方案1】:

请看下面没有udf的例子:

import pyspark.sql.functions as f
from pyspark import Row
from pyspark.shell import spark
from pyspark.sql.types import ArrayType, StructType, StructField, StringType

df = spark.createDataFrame([
    Row(values='[{"text":"Tea"},{"text":"GoldenGlobes"}]'),
    Row(values='[{"text":"GoldenGlobes"}]')
])

schema = ArrayType(StructType([
    StructField('text', StringType())
]))

df \
    .withColumn('array_of_str', f.from_json(f.col('values'), schema).text) \
    .show()

输出:

+--------------------+-------------------+
|              values|       array_of_str|
+--------------------+-------------------+
|[{"text":"Tea"},{...|[Tea, GoldenGlobes]|
|[{"text":"GoldenG...|     [GoldenGlobes]|
+--------------------+-------------------+

【讨论】:

  • 这给我带来了这个错误Can only star expand struct data types. Attribute: "ArrayBuffer(jsonData)"; 你知道我该如何解决这个问题吗?
  • @RamaSalahat 没有看到你的数据和代码很难想象,你能发布一个包含这些信息的问题吗?
  • 好的,我就这么做!
【解决方案2】:

如果你的列的类型是数组,那么这样的东西应该可以工作(未经测试):

from pyspark.sql import functions as F
from pyspark.sql import types as T

c = F.array([F.get_json_object(F.col("colname")[0], '$.text')),  
             F.get_json_object(F.col("colname")[1], '$.text'))])

df = df.withColumn("new_col", c)

或者如果长度不固定(我没有看到没有 udf 的解决方案):

F.udf(T.ArrayType())
def get_list(x):
    o_list = []
    for elt in x:
        o_list.append(elt["text"])
    return o_list

df = df.withColumn("new_col", get_list("colname"))

【讨论】:

  • 数组中可能有超过 2 个元素。长度不固定。
  • 那你将不得不使用一个udf,我会编辑答案
【解决方案3】:

分享 Java 语法:

import static org.apache.spark.sql.functions.from_json;
import static org.apache.spark.sql.functions.get_json_object;
import static org.apache.spark.sql.functions.col;
import org.apache.spark.sql.types.StructType;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import static org.apache.spark.sql.types.DataTypes.StringType;

Dataset<Row> df = getYourDf();

StructType structschema =
                DataTypes.createStructType(
                        new StructField[] {
                                DataTypes.createStructField("text", StringType, true)
                        });

ArrayType schema = new ArrayType(structschema,true);


df = df.withColumn("array_of_str",from_json(col("colname"), schema).getField("text"));

【讨论】:

    猜你喜欢
    • 2020-04-09
    • 2012-05-08
    • 2013-08-29
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    相关资源
    最近更新 更多