Pyspark中两个列表列的差异

Pyspark中两个列表列的差异,pyspark,apache-spark-sql,pyspark-sql,Pyspark,Apache Spark Sql,Pyspark Sql,我有一个数据框,其中有两列是列表类型的。 我试图得到第三列,它将这两列的差异作为列表放入一列中 例如: 假设以下数据框包含两列: +--------------+------------+ | col1| col2| +--------------+------------+ |[10, 20,30,40]| [10, 20]| +--------------+------------+ 我试图得到第三列,它的值是一个列表,其中包含col1中不在col2中

我有一个数据框,其中有两列是列表类型的。 我试图得到第三列,它将这两列的差异作为列表放入一列中

例如:

假设以下数据框包含两列:

+--------------+------------+
|          col1|        col2|
+--------------+------------+
|[10, 20,30,40]|    [10, 20]|
+--------------+------------+
我试图得到第三列,它的值是一个列表,其中包含col1中不在col2中的元素。因此,我的结果数据框如下所示:

+--------------+------------+---------+
|          col1|        col2|    col3 |
+--------------+------------+---------+
|[10, 20,30,40]|    [10, 20]| [30, 40]|
+--------------+------------+---------+
下面是一些创建示例数据帧的代码

df = spark.createDataFrame([(["10","20","30"],["10","20","30"])]["age","id"])

df.show()
+------------+------------+
|         age|          id|
+------------+------------+
|[10, 20, 30]|[10, 20, 30]|
+------------+------------+

df.select(df.age - df.id).show()
我尝试了上述不同的方法,但无法解决此问题。

您正在寻找(col1,col2),它返回col1中存在但不在col2中的元素,且不存在重复项

从pyspark.sql导入函数为F
df=spark.createDataFrame([([“10”、“20”、“30”]、[“10”、“20”、“30”])、([“10”、“20”、“30”]、[“10”、“20”、“20”])、([“10”、“20”、“30”]、[“10”、“20”、“50”])、[“年龄”、“id”])
df=df.withColumn('col3',F.array_除外('age','id'))
#如果您想得到两列之间的差异
#df=df.withColumn('col3',F.array_union)(F.array_except('age','id'),F.array_except('id','age'))
df.show()
如果您使用spark<2.4:

from pyspark.sql import types as T
from pyspark.sql import functions as F

df = spark.createDataFrame([(["10","20","30"],["10","20","30"]), (["10","20","30"],["10","20"]), (["10","20","30"],["10","20","50"])],["age","id"])

def arrayDiff(col1, col2):
    #set will remove duplicates
    diff = set(col1) - set(col2)
    return list(diff)

diff=F.udf(arrayDiff, T.ArrayType(T.StringType()))

df=df.withColumn('col3', diff('age', 'id'))

df.show()
输出:

+------------+------------+----+ 
|         age|          id|col3| 
+------------+------------+----+ 
|[10, 20, 30]|[10, 20, 30]|  []| 
|[10, 20, 30]|    [10, 20]|[30]| 
|[10, 20, 30]|[10, 20, 50]|[30]| 
+------------+------------+----+
您正在查找(col1,col2),它返回col1中存在但不在col2中的元素,且不存在重复项

从pyspark.sql导入函数为F
df=spark.createDataFrame([([“10”、“20”、“30”]、[“10”、“20”、“30”])、([“10”、“20”、“30”]、[“10”、“20”、“20”])、([“10”、“20”、“30”]、[“10”、“20”、“50”])、[“年龄”、“id”])
df=df.withColumn('col3',F.array_除外('age','id'))
#如果您想得到两列之间的差异
#df=df.withColumn('col3',F.array_union)(F.array_except('age','id'),F.array_except('id','age'))
df.show()
如果您使用spark<2.4:

from pyspark.sql import types as T
from pyspark.sql import functions as F

df = spark.createDataFrame([(["10","20","30"],["10","20","30"]), (["10","20","30"],["10","20"]), (["10","20","30"],["10","20","50"])],["age","id"])

def arrayDiff(col1, col2):
    #set will remove duplicates
    diff = set(col1) - set(col2)
    return list(diff)

diff=F.udf(arrayDiff, T.ArrayType(T.StringType()))

df=df.withColumn('col3', diff('age', 'id'))

df.show()
输出:

+------------+------------+----+ 
|         age|          id|col3| 
+------------+------------+----+ 
|[10, 20, 30]|[10, 20, 30]|  []| 
|[10, 20, 30]|    [10, 20]|[30]| 
|[10, 20, 30]|[10, 20, 50]|[30]| 
+------------+------------+----+

请注意
array\u except()
的副作用,它将从最终列表中删除重复项,这可能会删除一些额外的记录。很抱歉,我没有得到它。数组_except将返回col1中的元素,但不返回col2中的元素,没有重复项。哪些记录可能会被删除?请检查年龄=[“10”、“20”、“30”、“30”],id=[“10”、“20”],
array\u除
外将生成
[“30”]
而不是[“30”、“30”]。必须知道OP是否需要这种副作用,或者在原始阵列中没有重复。看起来像array_,但函数在2.4.0 spark版本中工作。您如何在2.3版本中解决上述问题?我已编辑了我的答案以解决此问题。请看一看。
array\u except()
的副作用,它会从最终列表中删除重复项,这可能会删除一些额外的记录。很抱歉,我没有得到它。数组_except将返回col1中的元素,但不返回col2中的元素,没有重复项。哪些记录可能会被删除?请检查年龄=[“10”、“20”、“30”、“30”],id=[“10”、“20”],
array\u除
外将生成
[“30”]
而不是[“30”、“30”]。必须知道OP是否需要这种副作用,或者在原始阵列中没有重复。看起来像array_,但函数在2.4.0 spark版本中工作。您如何在2.3版本中解决上述问题?我已编辑了我的答案以解决此问题。请看一看。