如何在PySpark的dataframe列中转换JSON字符串?

时间:2019-07-19 08:39:15

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

我有一个如下所示的pyspark数据框

+--------------------+---+
|            _c0|_c1|
+--------------------+---+
|{"object":"F...|  0|
|{"object":"F...|  1|
|{"object":"F...|  2|
|{"object":"E...|  3|
|{"object":"F...|  4|
|{"object":"F...|  5|
|{"object":"F...|  6|
|{"object":"S...|  7|
|{"object":"F...|  8|

_c0包含字典形式的字符串。

'{"object":"F","time":"2019-07-18T15:08:16.143Z","values":[0.22124142944812775,0.2147877812385559,0.16713131964206696,0.3102800250053406,0.31872493028640747,0.3366488814353943,0.25324496626853943,0.14537988603115082,0.12684473395347595,0.13864757120609283,0.15222792327404022,0.238663449883461,0.22896413505077362,0.237777978181839]}'

如何将上述字符串转换成字典形式,并获取每个键值对并将其存储到变量中?我不想将其转换为熊猫,因为它很昂贵。

4 个答案:

答案 0 :(得分:0)

df.rdd.map将给定功能应用于数据的每一行。我尚未使用spark的python变体,但它可以像这样工作:

import json

def wrangle(row):
   tmp = json.loads(row._c0)
   return (row._c1, tmp['object'], tmp['time'], tmp['values'])

df.rdd.map(wrangle)  # should yield a new frame/rdd with the object split

如何处理列的问题可能会那样工作,但是您似乎已经想通了。

这会将JSON格式的字符串加载到Python对象,并返回包含必需元素的元组。也许您需要返回一个Row对象而不是一个元组,但是,如上所述,我还没有使用spark的python部分。

答案 1 :(得分:0)

对于Scala的Dataset.withColumnfrom_json标准函数,您应该使用Spark API的等效项。

答案 2 :(得分:0)

扩展@Jacek Laskowski的帖子: 首先创建struct列的架构。然后使用from_json将字符串列转换为结构。最后,我们使用嵌套的架构结构提取新列(我们使用需要python 3.6的f字符串)。在结构类型上,您可以直接使用.select对嵌套结构进行操作。

schema = StructType([StructField("object",StringType()),
                    StructField("time",StringType()),
                    StructField("values",ArrayType(FloatType()))])

df=df.withColumn('_c0',f.from_json('_c0', schema))

select_list = ["_c0","_c1"] + [f.col(f'_c0.{column}').alias(column) for column in ["object","time","values"]] 
df.select(*select_list).show()

输出(仅排在第一行)

+--------------------+---+------+--------------------+--------------------+
|                 _c0|_c1|object|                time|              values|
+--------------------+---+------+--------------------+--------------------+
|[F, 2019-07-18T15...|  0|     F|2019-07-18T15:08:...|[0.22124143, 0.21...|
|[F, 2019-07-18T15...|  1|     F|2019-07-18T15:08:...|[0.22124143, 0.21...|
+--------------------+---+------+--------------------+--------------------+

答案 3 :(得分:0)

我做了什么

具有 JSON 字符串的列的值类似于

"{\"arm\": \"1\", \"wtvec\": [1, 1, 0.4], \"td\": \"current|0.01\", \"MABparam\": [[340, 1000], [340, 1000], [340, 1000], [340, 1000], [340, 1000], [340, 1000], [340, 1000], [340, 1000]], \"seg\": \"c2\"}"

做了一个简单的UDF

def htl_id(x):
    try:
        return int(json.loads(x)['arm'])
    except:
        raise Exception(x)

htlid_udf = udf(htl_id, IntegerType())

然后在我的情况下提取名为“arm”的列,

cdm.withColumn('arm', htlid_udf(col('logString')))

其他答案让你有架构,什么不是,这对我来说并不重要