2017-08-30 22 views
0

我在Spark DF中有一个Map列,并且想要在特定键上过滤此列(即,如果地图中的键与所需值匹配,则保留该列)。如何检查Pyspark地图中是否存在关键字或值

例如,我的模式被定义为:

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

我的样本数据是:

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

有什么办法来筛选的行我DF其中,“一”是“等级“不使用爆炸()?

是否有比给定的json更好的模式表示?

+0

'explode'可能是最好的解决方案。如果你不想使用它,你将不得不写一个UDF – MaFF

+0

谢谢@Marie。您能否建议我如何编写一个UDF来做到这一点,或者提供关于访问Map类型的键值属性的指导。我也尝试通过sqlContext.sql(“select test.df中的select rank.key”)访问Map键,但这不起作用。 – Stephan

回答

1

使用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| 
    +----------+-------------------+------+ 
相关问题