【问题标题】:Finding columns with Null values and write them in a new column per each record in Pyspark查找具有 Null 值的列并将它们写入 Pyspark 中每条记录的新列中
【发布时间】:2020-11-23 07:47:20
【问题描述】:

我有一个场景,我必须为每条记录查找具有 Null 值的列,并将所有此类列名称写入单独的列中。

示例: 我有这个数据框:

+---------+---+------------+-----------+------+-------+
|firstName|age|jobStartDate|isGraduated|gender| salary|
+---------+---+------------+-----------+------+-------+
|     null|se3|  2006-01-01|          8|     M|      F|
|     null| a3|        null|       True|     F|   null|
|   Robert| 37|  1992-01-01|       null|     M|5000.50|
+---------+---+------------+-----------+------+-------+

预期结果应如下所示:

+---------+---+------------+-----------+------+-------+----------------------+
|firstName|age|jobStartDate|isGraduated|gender| salary|       Missing Columns|
+---------+---+------------+-----------+------+-------+----------------------+
|     null|se3|  2006-01-01|          8|     M|      F|             firstName|
|     null| a3|  2006-01-02|       True|     F|   null|      firstName,salary|
|   Robert| 37|  1992-01-01|       null|     M|5000.50|           isGraduated|
+---------+---+------------+-----------+------+-------+----------------------+

我编写了一半符合我预期结果的代码:

def find_exceptions(df,mand_cols = ['firstName','jobStartDate','salary']):
  miss = "Missing: "
  for column in mand_cols:
    if df[column] is None:
      miss = miss + column + ","
  return miss

我能够将缺失值收集为列表:

temp = sourceDF.rdd.map(find_exceptions)
temp.collect()
#result: 
['Missing: firstName,', 'Missing: firstName,jobStartDate,salary,', 'Missing: ']

我发现很难将其实际写入新专栏。我对 Spark 还很陌生,如果有人能帮我解决这个问题,我将不胜感激。

【问题讨论】:

    标签: python scala apache-spark pyspark databricks


    【解决方案1】:

    您可以分三步完成。

    第 1 步:创建一个大小为列数的数组。如果条目为空,则将数组中的相应元素设置为列名的名称,否则将值保留为空。

    第 2 步:过滤列名的数组

    第 3 步:连接以具有逗号分隔的列表

    df //step 1
        .withColumn("MissingColumns",
          array(
            when(col("firstName").isNull(),lit("firstName")),
            when(col("age").isNull(),lit("age")),
            when(col("jobStartDate").isNull(),lit("jobStartDate")),
            when(col("isGraduated").isNull(),lit("isGraduated")),
            when(col("gender").isNull(),lit("gender")),
            when(col("salary").isNull(),lit("salary"))
          )
        )
         //step 2
          .withColumn("MissingColumns",expr("filter(MissingColumns, c -> c IS NOT NULL)"))
         //step 3
          .withColumn("MissingColumns",concat_ws(",",col("MissingColumns")) )
    

    【讨论】:

    • 成功了。谢谢。请将 isNull 更正为 isNull(),以便我将其标记为正确答案。
    • 我的错。我在scala中运行了代码。 isNull() 在 python 中确实应该有括号。
    • 我尝试通过 for 循环在第一个 .withColumn() 中形成条件并使用它而不是手动编写整个条件。但它不起作用。你能给我推荐一个替代方案吗?
    • 可以把它写成一个循环,用这个替换数组语句:array(*[when(col(c).isNull(),lit(c)) for c in columns ])
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 2011-09-11
    • 2021-09-23
    相关资源
    最近更新 更多