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|
+------+-----------+------+------+-----+