withColumn()中的PySpark list()仅工作一次,然后AssertionError:col应该是Column

时间:2018-12-03 06:18:45

标签: pyspark

我有一个DataFrame,其中包含6个字符串列,名称分别为“ Spclty1” ...“ Spclty6”,另外6个字符串列则名为“ StartDt1” ...“ StartDt6”。我想将它们压缩并折叠成如下所示的列: [[Spclty1, StartDt1]...[Spclty6, StartDt6]]

我首先尝试将“ Spclty”列折叠成这样的列表:

DF = DF.withColumn('Spclty', list(DF.select('Spclty1', 'Spclty2', 'Spclty3', 'Spclty4', 'Spclty5', 'Spclty6')))

这是我第一次执行该代码时的工作,按预期提供了一个名为'Spclty'的新列,其中包含诸如['014', '124', '547', '000', '000', '000']之类的行。

然后,我在脚本中添加了一行,以对名为'StartDt1'...'StartDt6'的一组6个不同的字符串列执行相同的操作:

DF = DF.withColumn('StartDt', list(DF.select('StartDt1', 'StartDt2', 'StartDt3', 'StartDt4', 'StartDt5', 'StartDt6'))))

这引起了AssertionError: col should be Column

在我尝试不了所有东西之后,我再次尝试了原始操作(作为健全性检查):

DF.withColumn('Spclty', list(DF.select('Spclty1', 'Spclty2', 'Spclty3', 'Spclty4', 'Spclty5', 'Spclty6'))).collect()

并得到了如上所述的断言错误。

因此,最好理解为什么它只能第一次(仅)工作,但是主要的问题是:将列压缩为Spark中像字典一样的元素集合的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

.withColumn()希望将列对象作为第二个参数,并且您正在提供一个列表。

答案 1 :(得分:0)

谢谢。阅读了许多SO帖子之后,我想出了将一组列传递给col参数的语法,使用struct创建了一个包含值列表的输出列:

DF_tmp = DF_tmp.withColumn('specialties', array([
        struct(
         *(col("Spclty{}".format(i)).alias("spclty_code"),
         col("StartDt{}".format(i)).alias("start_date")) 
        )
        for i in range(1, 7)
      ]
))

因此,col()*col()的构造正是我想要的,而array([struct(...)])的方法则使我可以将'Spclty'和'StartDt'条目组合到字典列表中类元素。