将空值替换为PySpark中的其他数据框

时间:2019-08-22 15:33:50

标签: apache-spark pyspark null nan

我有一些有关产品(DF)的数据,但是有些没有描述。我有一个带有一些描述的excel文件(作为Map加载)。现在,我想用Map的值填充DF中的缺失值,并使用Pyspark保持描述的行不变。

DF
Id | Desc
01 | 'desc1'
02 | null
03 | 'desc3'
04 | null

Map
Key | Value
2   | 'desc2'
4   | 'desc4'

Output
Id | Desc
1  | 'desc1'
2  | 'desc2'
3  | 'desc3'
4  | 'desc4'

预先感谢

3 个答案:

答案 0 :(得分:0)

您需要确保DF.Id字段和Map.Key字段是相同的类型/值(当前,前导0看起来不一样) ,然后进行左联接,然后使用coalesce()选择所需的列。我的pySpark有点生锈,所以我将在scala中提供解决方案。逻辑应该相同。

val df = Seq(
    (1, "desc1"),
    (2, null),
    (3, "desc3"),
    (4, null)
).toDF("Id", "Desc")

val map = Seq(
    (2, "desc2"),
    (4, "desc4")
).toDF("Key", "Value")

df.show()
map.show()

df.join(map, df("Id") === map("Key"), "left")
  .select(
      df("Id"),
      coalesce(df("Desc"), $"Value").as("Desc")
      )
  .show()

收益:

+---+-----+
| Id| Desc|
+---+-----+
|  1|desc1|
|  2| null|
|  3|desc3|
|  4| null|
+---+-----+

+---+-----+
|Key|Value|
+---+-----+
|  2|desc2|
|  4|desc4|
+---+-----+

+---+-----+
| Id| Desc|
+---+-----+
|  1|desc1|
|  2|desc2|
|  3|desc3|
|  4|desc4|
+---+-----+

答案 1 :(得分:0)

在PySpark中,借助UDF:

schema = StructType([StructField("Index", IntegerType(), True),
                    StructField("Desc", StringType(), True)])

DF = sc.parallelize([(1, "desc1"), (2,None), (3,"desc3"), (4, None)]).toDF(schema)

myMap = {
      2: "desc2",
      4 : "desc4"
    }

myMapBroadcasted = sc.broadcast(myMap)

@udf(StringType())
def fillNone(Index, Desc):
  if Desc is None:
    if Index in myMapBroadcasted.value:
      return myMapBroadcasted.value[Index]
  return Desc

DF.withColumn('Desc', fillNone(col('Index'), col('Desc'))).show()

答案 2 :(得分:0)

很难知道您提供的数据集的cardinality ...此处可能会改变解决方案的一些示例:

  1. 如果“ DF”和“地图”重叠Desc ...我们应该如何优先排序具有“正确”描述的表?
  2. 您要创建的最终数据框是否需要完全包含ID或说明的列表?这些数据框中是否有完整列表?这也可能会改变解决方案。

我做了一些假设,以便您可以自己确定什么是正确的方法:

  • 我假设“ DF”包含ID的整个列表
  • 我假设“地图”仅具有ID的子集,并不完全包含“ DF”中存在的更广泛的ID集。

我在这里使用PySpark:

DF = DF.na.drop() # we'll eliminate the missing values from the parent dataframe
DF_Output = DF.join(Map, on = "ID", how = 'outer')