Pyspark 检查数组是否包含数组

Pyspark 检查数组是否包含数组,pyspark,Pyspark,我有一个数据集: number | matricule<array> | name<array> | model <array> ---------------------------------------------------------------- AA | [] | [7] | [7] ---------------------------------------

我有一个数据集:

number  |  matricule<array>   | name<array>  |    model <array>
----------------------------------------------------------------
AA      |  []                 |  [7]         |     [7]
----------------------------------------------------------------
AA      |  [9]                |  [4]         |     [9]
----------------------------------------------------------------
AA      |  [8]                |  [2]         |     [8, 2]
----------------------------------------------------------------
AA      |  [2]                |  [3, 4]      |     [3,4]
我尝试了以下代码:

def is_subset(a, b):
        if F.size(F.array_except(a, b)) == 0:
            return "True"
        else:
            return "False"
    validate = F.udf(is_subset)
    df_join = df_join.withColumn("Flag", validate(F.col("name"), F.col("model")))
    return df_join

I got an error:


Caused by: org.apache.spark.SparkException: Job aborted due to stage
in is_subset
AttributeError: 'NoneType' object has no attribute '_jvm'
我尝试了以下代码:

df_join = df_join.withColumn("Flag", F.when(
            ((F.size(F.expr(F.array_except(F.col("name"), F.col("model"))) == F.lit(0))) 
            & (F.size(F.expr(F.array_except(F.col("matricule"), F.col("model"))) != F.lit(0)))) , True
            ).otherwise(False))
我得到了这个错误:

TypeError: 'Column' object is not callable in this line ((F.size(F.expr(F.array_except(F.col("name"), F.col("model"))) == F.lit(0)))
预期结果:

number  |  matricule<array>   | name<array>  |    model <array>   | Flag
---------------------------------------------------------------------------
AA      |  []                 |  [7]         |     [7]            |   True
---------------------------------------------------------------------------
AA      |  [9]                |  [4]         |     [9]            |   False
---------------------------------------------------------------------------
AA      |  [8]                |  [2]         |     [8, 2]         |   False
---------------------------------------------------------------------------
AA      |  [2]                |  [3, 4]      |     [3,4]          |  True
编号|矩阵|名称|型号|标志
---------------------------------------------------------------------------
AA |[]|[7]|[7]|正确
---------------------------------------------------------------------------
AA |[9]|[4]|[9]|错误
---------------------------------------------------------------------------
AA |[8]|[2]|[8,2]|假
---------------------------------------------------------------------------
AA |[2]|[3,4]|[3,4]|对
有人能给我一个解决方案吗

谢谢

如果您不想保留副本: 如果要保留重复项,请执行以下操作: 这里必须使用udf,因为数组_intersect不保留重复项

def intersect(ar1,ar2):
     return [i for i in ar1 if i in ar2]

udf1= F.udf(intersect, ArrayType(LongType()))

df.withColumn("nm", udf1("name","model"))\
      .withColumn("nm1", udf1("matriculate","model"))\
      .withColumn("flag2", F.when((F.col("nm1")==F.col("matriculate"))&(F.size("matriculate")!=0),F.lit(False)).otherwise(F.lit(True)))\
      .withColumn("Flag", F.when((F.col("flag2")==F.lit(True))&(F.col("nm")!=F.col("name")), F.lit(False)).otherwise(F.col("flag2")))\
      .drop("nm","nm1","flag2").show()


+------+-----------+------+------+-----+
|number|matriculate|  name| model| Flag|
+------+-----------+------+------+-----+
|    AA|         []|   [7]|   [7]| true|
|    AA|        [9]|   [4]|   [9]|false|
|    AA|        [8]|   [2]|[8, 2]|false|
|    AA|        [2]|[3, 4]|[3, 4]| true|
+------+-----------+------+------+-----+
如果不想保留重复项: 如果要保留重复项,请执行以下操作: 这里必须使用udf,因为数组_intersect不保留重复项

def intersect(ar1,ar2):
     return [i for i in ar1 if i in ar2]

udf1= F.udf(intersect, ArrayType(LongType()))

df.withColumn("nm", udf1("name","model"))\
      .withColumn("nm1", udf1("matriculate","model"))\
      .withColumn("flag2", F.when((F.col("nm1")==F.col("matriculate"))&(F.size("matriculate")!=0),F.lit(False)).otherwise(F.lit(True)))\
      .withColumn("Flag", F.when((F.col("flag2")==F.lit(True))&(F.col("nm")!=F.col("name")), F.lit(False)).otherwise(F.col("flag2")))\
      .drop("nm","nm1","flag2").show()


+------+-----------+------+------+-----+
|number|matriculate|  name| model| Flag|
+------+-----------+------+------+-----+
|    AA|         []|   [7]|   [7]| true|
|    AA|        [9]|   [4]|   [9]|false|
|    AA|        [8]|   [2]|[8, 2]|false|
|    AA|        [2]|[3, 4]|[3, 4]| true|
+------+-----------+------+------+-----+


您可以使用sql函数来比较数组:我认为array_except是不被接受的。您也可以尝试调整此处答案中提到的udf:@mrjoseph谢谢您的回答。我怎样才能使用udf呢?@verojoucla我认为没有必要使用udf,而且效率很低。尝试我的解决方案您可以使用sql函数来比较数组:我认为array_Exception不被接受。您也可以尝试调整此处答案中提到的udf:@mrjoseph谢谢您的回答。我怎样才能使用udf呢?@verojoucla我认为没有必要使用udf,而且效率很低。试试我的解决办法我经过一次深入的测试后回来找你。很抱歉,这个逻辑不好,特别是当您使用array_intersect函数时,我们会丢失name和matricule中的一些数据。array_intersect返回元素的交集,没有重复项。您只丢失了副本,我认为这不是问题,因为您的问题中没有任何副本。谢谢您的回答。是的,但我在寻找数组中数组的存在性,数组不是数组。当然,当我说数组时,我的意思是数组A中的每个元素都应该存在于数组B中,以返回True。对于第二个数组“matricule”,如果数组模型中只存在一个元素,即使name数组的所有元素都存在于模型中,我也应该返回false。我用udf而不是array_intersect更新了答案,以保留重复项,如果这是我逻辑中唯一的漏洞。我对你所说的“数组中存在一个数组,而数组不是一个数组”的意思有点困惑。谢谢你,我来测试一下:)我在深入测试之后回到你身边。很抱歉,这个逻辑不好,特别是当您使用array_intersect函数时,我们会丢失name和matricule中的一些数据。array_intersect返回元素的交集,没有重复项。您只丢失了副本,我认为这不是问题,因为您的问题中没有任何副本。谢谢您的回答。是的,但我在寻找数组中数组的存在性,数组不是数组。当然,当我说数组时,我的意思是数组A中的每个元素都应该存在于数组B中,以返回True。对于第二个数组“matricule”,如果数组模型中只存在一个元素,即使name数组的所有元素都存在于模型中,我也应该返回false。我用udf而不是array_intersect更新了答案,以保留重复项,如果这是我逻辑中唯一的漏洞。我对你所说的“数组中存在一个数组,而数组不是数组”有点困惑。谢谢你,我来测试一下:)
def intersect(ar1,ar2):
     return [i for i in ar1 if i in ar2]

udf1= F.udf(intersect, ArrayType(LongType()))

df.withColumn("nm", udf1("name","model"))\
      .withColumn("nm1", udf1("matriculate","model"))\
      .withColumn("flag2", F.when((F.col("nm1")==F.col("matriculate"))&(F.size("matriculate")!=0),F.lit(False)).otherwise(F.lit(True)))\
      .withColumn("Flag", F.when((F.col("flag2")==F.lit(True))&(F.col("nm")!=F.col("name")), F.lit(False)).otherwise(F.col("flag2")))\
      .drop("nm","nm1","flag2").show()


+------+-----------+------+------+-----+
|number|matriculate|  name| model| Flag|
+------+-----------+------+------+-----+
|    AA|         []|   [7]|   [7]| true|
|    AA|        [9]|   [4]|   [9]|false|
|    AA|        [8]|   [2]|[8, 2]|false|
|    AA|        [2]|[3, 4]|[3, 4]| true|
+------+-----------+------+------+-----+