如何在Spark中向爆炸结构添加列?

时间:2017-09-13 18:46:12

标签: apache-spark dataframe pyspark

说我有以下数据:

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成为interface SkillProperty { [name: string] : number }; let skills: SkillProperty; skills = {}; // ok skills = { fire: 123 }; // ok skills = { ...skills, // ok ...{}, // ok ...extraSkills() // {} | { ice: number } is not assignable to type 'SkillProperty'. } function extraSkills() { if (whatever) { return {}; } return { ice: 321 }; } 结构的一部分......

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

1 个答案:

答案 0 :(得分: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']))

P.S。

Spark几乎不支持 inplace opreation。

因此,每当您想要 inplace 时,您需要实际执行替换