猿问

Pyspark:有条件地用空格连接列

鉴于我有下表:


ColA     |   ColB   |  ColC  |  ColD


Name         BA         CC       DA      

Name         BB         CC       DA

我想检查所有行的 ColB、ColC 和 ColD 值是否相同(名称始终相同)。如果是,我需要按原样返回我的 df 。如果不是,我应该附加那些与我的 ColA 不同的内容。


因此,在这种情况下,如果 B 列不一致,我的结果表应如下所示:


ColA       |   ColB   |  ColC  |  ColD


Name BA        BA         CC       DA      

Name BB        BB         CC       DA

我遇到了一些麻烦,但我想出了这个功能。然而,问题是我无法让它与空白一起工作。所以目前我的结果是这样的:


ColA       |   ColB   |  ColC  |  ColD


NameBA        BA         CC       DA      

NameBB        BB         CC       DA

功能:


def id(df, cols):

  """

  """

  def is_not_unique_col(df, x):

    """

    """

    if len(df.select(x).distinct().collect()) != 1:

      return True

    else:

      return False


  def concat_with_whitespace(*cols):

    """

    """

    return F.concat(*[F.coalesce(c, F.lit(" ")) for c in cols])


  non_unique_cols = [x for x in cols if is_not_unique_col(df, x)]

  if len(non_unique_cols)>0:

    df = df.withColumn("ColA_New", concat_with_whitespace("ColA", *non_unique_cols)).drop("ColA")

    df = df.withColumnRenamed("ColA_New", "ColA").drop("ColA_New")

    return df

  else:

    return df

我有这个is_not_unique_col函数,它检查列是否具有多个值。我对所有列运行它,那些返回 True 的列将附加到 non_unique_cols 列表中,该列表用作我的concat_with_whitespace函数的输入。我已F.lit(" ")在其中添加了此内容,以便获得空白。一切似乎都是正确的,但我无法让它发挥作用。如果有人能看一下,我将不胜感激,也许这是一些愚蠢的错误。


holdtom
浏览 110回答 1
1回答

哆啦的时光机

我会给你一个不使用任何 UDF 的解决方案。用于collect_set()获取具有非唯一值的列名列表from pyspark.sql import functions as Ffrom pyspark.sql.functions import *diff_col = [i for i in df.schema.names if \    (df.select(F.size(F.collect_set(i))).collect()[0][0] > 1)]对于连接:df.select(col("*"), concat(col("ColA"), lit(" "),concat(*diff_col))\        .alias("concat_col")).show()+----+----+----+----+----------+|ColA|ColB|ColC|ColD|concat_col|+----+----+----+----+----------+|Name|  BA|  CC|  DA|   Name BA||Name|  BB|  CC|  DA|   Name BB|+----+----+----+----+----------+或者,如果您希望多列的连接之间有空格(如果您有多列非唯一值),则:df.select(col("*"), concat(col("ColA"), lit(" "),\    concat(*[F.concat(col(i),F.lit(" "))for i in diff_col])).alias("concat_col")).show()
随时随地看视频慕课网APP

相关分类

Python
我要回答