Apache spark 如何在Pyspark中筛选数组列中的值

Apache spark 如何在Pyspark中筛选数组列中的值,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我有一个pyspark Dataframe,它包含许多列,其中列作为数组类型和字符串列: numbers <Array> | name<String> ------------------------------|---------------- ["160001","160021"] | A ------------------------------|---------------- ["160001","

我有一个
pyspark Dataframe
,它包含许多列,其中列作为数组类型和字符串列:

numbers  <Array>              |    name<String>
------------------------------|----------------
["160001","160021"]           |     A
------------------------------|----------------
["160001","1600", "42345"]    |     B
------------------------------|----------------
["160001","9867", "42345"]    |     C
------------------------------|----------------
["160001","8650", "2345"]     |     A
------------------------------|----------------
["2456","78568", "42345"]     |     B
-----------------------------------------------
在第3行和第4行中,我有一个数字列,其中包含一个4位数的数字,但列名与“B”==>不同,因此我应该跳过它们

例如:

------------------------------|----------------
["160001","9867", "42345"]    |     C
------------------------------|----------------
["160001","8650", "2345"]     |     A
------------------------------|----------------
预期结果:

    numbers  <Array>              |    name<String>
------------------------------|----------------
["160001","160021"]           |     A
------------------------------|----------------
["160001","1600", "42345"]    |     B
------------------------------|----------------
["160001", "42345"]           |     C
------------------------------|----------------
["160001"]                    |     A
------------------------------|----------------
["2456","78568", "42345"]     |     B
-----------------------------------------------
number |名称
------------------------------|----------------
[“160001”、“160021”]| A
------------------------------|----------------
[“160001”、“1600”、“42345”]B
------------------------------|----------------
[160001”,“42345”]C
------------------------------|----------------
[“160001”]| A
------------------------------|----------------
[“2456”、“78568”、“42345”]B
-----------------------------------------------
我怎么做?
谢谢

您需要编写一个udf来执行数组过滤器,并将其与
when
子句一起使用,以便将udf应用于特定条件,如
其中name==B

from pysparl.sql.functions import udf, col, when
from pyspark.sql.types import ArrayType, StringType

filter_array_udf = udf(lambda arr: [x for x in arr if len(x) > 4], "array<string>")
# if string schema is not supported then use the next commented line
# filter_array_udf = udf(filter_array, ArrayType(StringType()))

df = df.withColumn("numbers", when(col("name") == "B", filter_array_udf(col("numbers"))).otherwise(col("numbers")))
从pysparl.sql.functions导入udf,col,当
从pyspark.sql.types导入ArrayType、StringType
filter_array_udf=udf(lambda arr:[x代表arr中的x,如果len(x)>4],“array”)
#如果不支持字符串模式,则使用下一个注释行
#filter\u array\u udf=udf(filter\u array,ArrayType(StringType()))
df=df.withColumn(“numbers”),当(col(“name”)=“B”,filter\u array\u udf(col(“numbers”))。否则(col(“numbers”))

您需要编写一个udf来执行数组过滤器,并将其与
when
子句一起使用,以便将udf应用于特定条件,如
其中name==B

from pysparl.sql.functions import udf, col, when
from pyspark.sql.types import ArrayType, StringType

filter_array_udf = udf(lambda arr: [x for x in arr if len(x) > 4], "array<string>")
# if string schema is not supported then use the next commented line
# filter_array_udf = udf(filter_array, ArrayType(StringType()))

df = df.withColumn("numbers", when(col("name") == "B", filter_array_udf(col("numbers"))).otherwise(col("numbers")))
从pysparl.sql.functions导入udf,col,当
从pyspark.sql.types导入ArrayType、StringType
filter_array_udf=udf(lambda arr:[x代表arr中的x,如果len(x)>4],“array”)
#如果不支持字符串模式,则使用下一个注释行
#filter\u array\u udf=udf(filter\u array,ArrayType(StringType()))
df=df.withColumn(“numbers”),当(col(“name”)=“B”,filter\u array\u udf(col(“numbers”))。否则(col(“numbers”))

自Spark 2.4以来,您可以使用高阶函数
过滤器来过滤阵列。将此表达式与
if
表达式相结合,可以解决以下问题:

df.selectExpr("if(name != \'B', FILTER(numbers, x -> length(x) != 4), numbers) AS numbers", "name")

由于Spark 2.4,您可以使用高阶函数
过滤器
来过滤阵列。将此表达式与
if
表达式相结合,可以解决以下问题:

df.selectExpr("if(name != \'B', FILTER(numbers, x -> length(x) != 4), numbers) AS numbers", "name")

谢谢你的回答,我收到了这个错误:IllegalArgumentException:u'otherwise()只能应用于以前由when()生成的列。@verojoucla我已经修复了这个错误。这是由于支架不匹配造成的。谢谢:)如有必要,请接受并投票helped@verojoucla哈哈哈,在看到你的评论之前,我正试图解决这个问题。嗨@pissall:)你对这个问题有什么想法吗?谢谢,第二个解决方案是有效的,但仅适用于一小部分数据,当我将其应用于全部数据时无效谢谢你的回答我得到了这个错误:IllegalArgumentException:u'否则()只能应用于以前由when()@verojoucla生成的列我已修复了错误。这是由于支架不匹配造成的。谢谢:)如有必要,请接受并投票helped@verojoucla哈哈哈,在看到你的评论之前,我正试图解决这个问题。嗨@pissall:)你对这个问题有什么想法吗?谢谢,第二个解决方案是工作,但只在一小部分数据上,当我将其应用于全部数据时,它不起作用