添加引号以列出对象以格式化为字典 pyspark

问题描述 投票:0回答:1

我的数据框有一列

data
,其中包含长字符串中的日期和值信息。为此,我们将该列称为
x
,其格式如下:

x = "{date1:val1, date2:val2, date3:val3, ...}" 

我想最终分解这些数据,以便创建两个新列,一列用于日期,一列用于验证。为了利用

explode
函数,我知道该列必须格式化为数组,而不是字符串。到目前为止,为了解决这个问题,我删除了字符串开头和结尾处的大括号:

from pyspark.sql import functions as F

data = data.withColumn('x_1', F.regexp.replace('x', r'\{', ''))
data = data.withColumn('x_1', F.regexp.replace('x_1', r'\}', '') 

然后我创建了一个列表变量:

data = data.withColumn('x_list', F.split('x_1', ', '))

我现在有了

x_list = [date1:val1, date2:val2, date3:val3, ...]

我现在需要的是在每个列表元素周围添加引号,这样我最终会得到

['date1':'val1', 'date2':'val2', 'date3':'val3', ...]

我相信可以迭代列表并使用正则表达式使用冒号(:)作为分割点来添加引号,但我正在努力解决如何做到这一点。我相信它看起来像:

for l in x_list:
   #some regex expression

或者,我考虑过为每个列表元素创建一个子列表,但我不确定如何使用这些子列表来创建两个新列。

python pyspark pandas-explode
1个回答
0
投票

您的字符串不是有效的 json,也不是有效的字典字符串。你可以这样做:

import pyspark.sql.functions as F
from pyspark.sql.types import StringType, ArrayType

@F.udf(returnType=ArrayType(StringType()))
def parse_(s):
    if s is None: return None
    return [item.split(":")[1] for item in s.strip("{}").split(",")]

df = spark.createDataFrame([[1, "{date1:val1, date2:val2, date3:val3}"]], schema=["col1", "col2"])
display(df.withColumn("date", F.explode(parse_("col2"))))
© www.soinside.com 2019 - 2024. All rights reserved.