我的数据框有一列
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
或者,我考虑过为每个列表元素创建一个子列表,但我不确定如何使用这些子列表来创建两个新列。
您的字符串不是有效的 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"))))