选择数据框的所有列作为StructType

时间:2017-12-06 21:21:57

标签: python apache-spark pyspark apache-spark-sql

在pyspark中,我有两个数据帧,dfA和dfB,具有复杂的模式。模式中的常见列是“时间”。我想创建一个新的数据帧,这是两者的结合,这样我就可以按时排序,但是我不想丢失原始数据帧中的任何内容。我无法弄清楚如何从一个原始数据帧中获取所有内容并将它们组合在一个新的unionType中。

也就是说,如果我有

# dfA
root
 |--time
 |--fieldA
 |--fieldB

# dfB
root
 |--time
 |--fieldC
 |--fieldD

我想创建一个具有架构的联合数据框

# root
   |--time
   |--dfA
       |--time
       |--fieldA
       |--fieldB
   |--dfB
       |--time
       |--fieldC
       |--fieldD  

在联合之后,字段dfA和dfB有时会为空,具体取决于该行来自哪个原始数据帧。

我想我可以通过

来定义公共模式
common_schema = T.StructType([T.StructField('time', T.TimestampType()),
                              T.StructField('dfA', dfA.schema, True),
                              T.StructField('dfB', dfB.schema, True)])

但后来我陷入了如何从数据框作为列中选择所有内容的语法。我正在寻找像

这样的东西
commonA = dfA.select('time', 
                     F.col('*').alias('dfA'))
commonB = dfB.select('time',
                     F.col('*').alias('dfB'))
common_df = commonA.union(commonB)

但这是非法使用' *'

1 个答案:

答案 0 :(得分:0)

  

选择数据框的所有列作为StructType

from pyspark.sql.functions import struct, lit

commonA = dfA.select("time", struct(*[c for c in df.columns]).alias("dfA"))
commonB = dfB.select("time", struct(*[c for c in df.columns]).alias("dfB"))

但是这不能像所描述的那样联合起来。你可以:

commonA_ = commonA.select("time", "dfA", lit(None).cast(dfB.schema).alias("dfB"))
commonB_ = commonB.select("time", lit(None).cast(dfA.schema).alias("dfA"), "dfB")
commonA_.union(commonB_)

但听起来你正在寻找更像外连接的东西

dfA.alias("A").join(dfB.alias("B"), ["time"], "fullouter")