使用pyspark在不在列表中时插入新列

使用pyspark在不在列表中时插入新列,pyspark,Pyspark,我有一个火花: col1 col2 col3 col4 A a1 null s A a2 a2 g A null a3 m B a2 a2 g B a3 a3 g 当col2和col3都缺少以下列表中的元素时,我想插入新行: list = ["a1", "a2", "a3", "b4", "c7"] 因为在本例中,col

我有一个火花:

col1  col2     col3   col4
A      a1      null     s
A      a2      a2       g
A      null    a3       m
B      a2      a2       g
B      a3      a3       g
当col2和col3都缺少以下列表中的元素时,我想插入新行:

list = ["a1", "a2", "a3", "b4", "c7"]    
因为在本例中,col2和col3都缺少b4和c7,所以我应该有以下内容:

col1  col2     col3   col4
A      a1      null     s
A      a2      a2       g
A      null    a3       m
B      a2      a2       g
B      a3      a3       g

A      b4      b4       k
A      c7      c7       k
B      b4      b4       k
B      c7      c7       k
最后4行是我想添加的(这是一个示例,但实际df更大)。
有没有关于如何编码的想法?

尝试一下,使用
窗口函数
分解
逻辑(
spark2.4+
):


使用
窗口功能和
分解逻辑(
spark2.4+
)尝试此操作:


在col4中,最后4行的k来自哪里?或者它只是一个我们应该加上的常数?另外,难道不应该为B加上一行col2和col3作为a吗?Mohammad Murtaza Hashmi是的,你完全正确-只是一个常数加上一行B作为a,最后4行的k在col4中来自哪里?或者它只是一个我们应该加上的常数?另外,难道不应该为B加上一行col2和col3作为a1Mohammad Murtaza Hashmi是的,你完全正确-只是一个常数加上一行B作为a1
df.show() #sample dataframe

#+----+----+----+----+
#|col1|col2|col3|col4|
#+----+----+----+----+
#|   A|  a1|null|   s|
#|   A|  a2|  a2|   g|
#|   A|null|  a3|   m|
#|   B|  a2|  a2|   g|
#|   B|  a3|  a3|   g|
#+----+----+----+----+

from pyspark.sql import functions as F
from pyspark.sql.window import Window

w=Window().partitionBy("col1")
w1=Window().partitionBy("col1").orderBy(F.lit(1))

df\
  .withColumn("col1_2",F.flatten(F.collect_list(F.array("col2","col3")).over(w)))\
  .withColumn("list", F.array(*[F.lit(x) for x in list]))\
  .withColumn("except",F.array_except("list","col1_2"))\
  .withColumn("rowNum", F.row_number().over(w1))\
  .withColumn("max",F.max("rowNum").over(w))\
  .withColumn("col2", F.when(F.col("rowNum")==F.col("max"), F.array_union(F.array("col2"),F.col("except")))\
                       .otherwise(F.array(F.col("col2"))))\
  .withColumn("col3", F.when(F.col("rowNum")==F.col("max"),F.array_union(F.array("col3"),F.col("except")))\
                       .otherwise(F.array(F.col("col3")))).select(*[x for x in df.columns])\
  .withColumn("col5", F.when(F.size("col2")>1, F.expr("""array_repeat('k',size(col2)-1)"""))\
                           .otherwise(F.array("col4")))\
  .withColumn("col4", F.when(F.size("col2")>1,F.flatten(F.array(F.array("col4"),"col5")))\
                         .otherwise(F.array("col4"))).drop("col5")\
  .withColumn("zipped", F.explode(F.arrays_zip("col2","col3","col4")))\
  .select("col1","zipped.*")\
  .show()

#+----+----+----+----+
#|col1|col2|col3|col4|
#+----+----+----+----+
#|   B|  a2|  a2|   g|
#|   B|  a3|  a3|   g|
#|   B|  a1|  a1|   k|
#|   B|  b4|  b4|   k|
#|   B|  c7|  c7|   k|
#|   A|  a1|null|   s|
#|   A|  a2|  a2|   g|
#|   A|null|  a3|   m|
#|   A|  b4|  b4|   k|
#|   A|  c7|  c7|   k|
#+----+----+----+----+