如何检查Pyspark Map中是否存在键或值

时间:2017-08-30 15:58:35

标签: python pyspark-sql

我在Spark DF中有一个Map列,想要在特定键上过滤此列(例如,如果地图中的键与所需值匹配,则保留行。)

例如,我的架构定义为:

df_schema = StructType(
  [StructField('id', StringType()),
   StructField('rank', MapType(StringType(), IntegerType()))]
)

我的示例数据是:

{ "id": "0981850006", "rank": {"a": 1} }

有没有办法在不使用explode()的情况下在“a”处于“rank”的行上过滤我的df?

对于给定的json,是否有比我定义的更好的模式表示?

1 个答案:

答案 0 :(得分:2)

使用rank.key访问密钥意味着rankStructType()。尽管爆炸可能是最佳解决方案,但我们可以构建一个UDF来评估k是否是rank的关键。

首先让我们创建我们的数据帧:

from pyspark.sql.types import *
df_schema = StructType(
  [StructField('id', StringType()),
   StructField('rank', MapType(StringType(), IntegerType()))]
)
df = spark.createDataFrame([
    ["0981850006", {"a": 1}], 
    ["0981850006", {"b": 2, "c": 3}], 
], df_schema)

现在我们的UDF:

def isKey(k,d):
    return k in d.keys()

isKey_udf = lambda k: psf.udf(lambda d: isKey(k,d), BooleanType())

给出了:

df.withColumn(
    "is_key", 
    isKey_udf('a')(df.rank)
)
    +----------+-------------------+------+
    |        id|               rank|is_key|
    +----------+-------------------+------+
    |0981850006|        Map(a -> 1)|  true|
    |0981850006|Map(b -> 2, c -> 3)| false|
    +----------+-------------------+------+