【问题标题】:How to add column to exploded struct in Spark?如何将列添加到 Spark 中的爆炸结构?
【发布时间】:2017-09-15 10:13:02
【问题描述】:

假设我有以下数据:

{"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
  • data.bar

我希望 data.bar 成为 data 结构的一部分...

如何在展开的结构中添加列,而不是添加顶级列?

【问题讨论】:

标签: apache-spark dataframe pyspark


【解决方案1】:
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 几乎不支持 inplace 操作。

所以每次你想inplace,你实际上需要replace

【讨论】:

  • 这绝对是朝着正确的方向发展!有没有办法在不知道data 的内容的情况下做到这一点(当然data.foo 除外)?我编辑了我的问题,添加了一个额外的 data.lol 列,以使这一点更清楚。
猜你喜欢
  • 2022-01-16
  • 2018-04-27
  • 2018-06-27
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
相关资源
最近更新 更多