Spark DataFrame ArrayType 或 MapType 用于检查列中的值

Posted

技术标签:

【中文标题】Spark DataFrame ArrayType 或 MapType 用于检查列中的值【英文标题】:Spark DataFrame ArrayType or MapType for checking for value in column 【发布时间】:2018-10-30 15:47:10 【问题描述】:

我有一个 pyspark 数据框,其中一列是 ID 列表。例如,我想获取其中具有特定 ID 的行数。

AFAIK 与我相关的两种列类型是 ArrayTypeMapType。我可以使用 map 类型,因为检查 map/dict 中的成员身份比检查数组中的成员身份更有效。

但是,要使用地图,我需要使用自定义 udf 而不是内置 (scala) 函数 array_contains 进行过滤

MapType 我可以做到:

from pyspark.sql.types import BooleanType
from pyspark.sql.functions import udf

df = spark.createDataFrame([("a-key", "345": True, "123": True)], ["key", "ids"])

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

def map_udf(key):
    return udf(lambda d: is_in_map(key, d), BooleanType())

c = df.filter(map_udf("123")(df.ids)).count()

或者使用ArrayType 我可以:

from pyspark.sql.functions import array_contains

df = spark.createDataFrame([("a-key", ["345", "123"])], ["key", "ids"])
c = df.filter(array_contains(df.ids, "123")).count()

我的第一反应是使用MapArray,因为检查地图内的成员(我认为)效率更高。

另一方面,内置函数 array_contains 执行 scala 代码,我假设我调用的任何 scala 定义的函数都比将列 dict 返回到 python 上下文和检查k in d.keys()

要检查此(多值)列中的成员资格,最好使用MapType 还是ArrayType pyspark.sql.types

更新

有一个列方法 pyspark.sql.Column.getItem 这意味着我可以在没有 python udf 的情况下按成员身份进行过滤

【问题讨论】:

首先,UDF 会降低性能。其次,我会选择ArrayType,因为ID 可以具有任意 某些ID 的计数值。 地图性能更高,在 Scala + Spark 中我使用了 df.where(df("ids").getItem("123") === true),它使用标准 Dataframe API 和 df("ids").getItem("123") 返回具有地图值或 null 的列,我怀疑 Pyspark 有类似的东西,所以会以 sparks 本机速度。 有@alexeipab 谢谢 嘿 @alexeipab 感谢 agian 的回答,如果你把它写出来,我会接受它 【参考方案1】:

地图性能更高,我在 Scala + Spark 中使用过

df.where(df("ids").getItem("123") === true)

它使用标准 Dataframe API 并且 df("ids").getItem("123") 返回 Column 的值为 map 或 null,它将以 Spark 的本机速度运行。 Pyspark 开发人员说 Pyspark 也有这个 API。

【讨论】:

以上是关于Spark DataFrame ArrayType 或 MapType 用于检查列中的值的主要内容,如果未能解决你的问题,请参考以下文章

在 SPARK 2.1 中传递包含 ArrayType 列的 javaRDD 时,createDataFrame() 抛出异常

如何将多维数组添加到现有的 Spark DataFrame

使用 pyspark 将 StructType、ArrayType 转换/转换为 StringType(单值)

将 Spark 中的多个 ArrayType 列合并为一个 ArrayType 列

SyntaxError:使用 ArrayType 创建 DataFrame 时语法无效

spark中混合数据的ArrayType