Apache spark 如何在Spark中向分解结构添加列?
假设我有以下数据:Apache spark 如何在Spark中向分解结构添加列?,apache-spark,dataframe,pyspark,Apache Spark,Dataframe,Pyspark,假设我有以下数据: {"id":1, "payload":[{"foo":1, "lol":2},{"foo":2, "lol":2}]} 我想分解有效载荷并在其中添加一列,如下所示: df = df.select('id', F.explode('payload').alias('data')) df = df.withColumn('data.bar', F.col('data.foo') * 2) 但是,这会导致数据框包含三列: id 数据 data.bar 我希望data.bar
{"id":1, "payload":[{"foo":1, "lol":2},{"foo":2, "lol":2}]}
我想分解有效载荷并在其中添加一列,如下所示:
df = df.select('id', F.explode('payload').alias('data'))
df = df.withColumn('data.bar', F.col('data.foo') * 2)
但是,这会导致数据框包含三列:
id
数据
data.bar
data.bar
成为data
结构的一部分
如何将列添加到分解结构中,而不是添加顶级列
df = df.withColumn('data', f.struct(
df['data']['foo'].alias('foo'),
(df['data']['foo'] * 2).alias('bar')
))
这将导致:
root
|-- id: long (nullable = true)
|-- data: struct (nullable = false)
| |-- col1: long (nullable = true)
| |-- bar: long (nullable = true)
更新:
def func(x):
tmp = x.asDict()
tmp['foo'] = tmp.get('foo', 0) * 100
res = zip(*tmp.items())
return Row(*res[0])(*res[1])
df = df.withColumn('data', f.UserDefinedFunction(func, StructType(
[StructField('foo', StringType()), StructField('lol', StringType())]))(df['data']))
附言
Spark几乎不支持就地操作
因此,每次您想在原地执行时,实际上需要执行替换。您必须重建模式,使用
选择,或使用自定义项来修改数据-这里介绍了几乎所有这些选项:可能的重复方向肯定是正确的!有没有一种方法可以在不知道data
内容的情况下执行此操作(当然data.foo
除外)?我编辑了我的问题,添加了一个额外的data.lol
列,以使问题更清楚。