2017-02-07 113 views
1

假设我有以下的情况下如何检查数组列是pyspark数据帧的另一列阵列内

from pyspark.sql.types import * 
schema = StructType([ # schema 
    StructField("id", StringType(), True), 
    StructField("ev", ArrayType(StringType()), True), 
    StructField("ev2", ArrayType(StringType()), True),]) 
df = spark.createDataFrame([{"id": "se1", "ev": ["ev11", "ev12"], "ev2": ["ev11"]}, 
          {"id": "se2", "ev": ["ev11"], "ev2": ["ev11", "ev12"]}, 
          {"id": "se3", "ev": ["ev21"], "ev2": ["ev11", "ev12"]}, 
          {"id": "se4", "ev": ["ev21", "ev22"], "ev2": ["ev21", "ev22"]}], 
          schema=schema) 

这给了我:

​​

我想创建一个布尔值的新列(或仅选择真实情况),其中“ev”列的内容位于“ev2”列内,返回:

df_target.show() 
+---+------------+------------+ 
| id|   ev|   ev2| 
+---+------------+------------+ 
|se2|  [ev11]|[ev11, ev12]| 
|se4|[ev21, ev22]|[ev21, ev22]| 
+---+------------+------------+ 

或:

df_target.show() 
+---+------------+------------+-------+ 
| id|   ev|   ev2|evInEv2| 
+---+------------+------------+-------+ 
|se1|[ev11, ev12]|  [ev11]| false| 
|se2|  [ev11]|[ev11, ev12]| true| 
|se3|  [ev21]|[ev11, ev12]| false| 
|se4|[ev21, ev22]|[ev21, ev22]| true| 
+---+------------+------------+-------+ 

我使用isin方法尝试:

df.withColumn('evInEv2', df['ev'].isin(df['ev2'])).show() 
+---+------------+------------+-------+ 
| id|   ev|   ev2|evInEv2| 
+---+------------+------------+-------+ 
|se1|[ev11, ev12]|  [ev11]| false| 
|se2|  [ev11]|[ev11, ev12]| false| 
|se3|  [ev21]|[ev11, ev12]| false| 
|se4|[ev21, ev22]|[ev21, ev22]| true| 
+---+------------+------------+-------+ 

但它看起来像它只是检查它是否在同一阵列。

我还从pyspark.sql.functions试过array_contains功能,但仅接受一个对象,而不是一个数组进行检查。

即使是因为措辞正确的问题而寻找此问题,我也遇到了困难。

谢谢!

回答

3

以下是使用udf的选项,我们检查evev2之间的差异长度。当结果数组的长度为0ev的所有元素都包含在ev2内时,我们返回True;否则False

def contains(x,y): 
    z = len(set(x) - set(y)) 
    if z == 0: 
    return True 
    else: 
    return False 

contains_udf = udf(contains) 
df.withColumn("evInEv2", contains_udf(df.ev,df.ev2)).show() 
+---+------------+------------+-------+ 
| id|   ev|   ev2|evInEv2| 
+---+------------+------------+-------+ 
|se1|[ev11, ev12]|  [ev11]| false| 
|se2|  [ev11]|[ev11, ev12]| true| 
|se3|  [ev21]|[ev11, ev12]| false| 
|se4|[ev21, ev22]|[ev21, ev22]| true| 
+---+------------+------------+-------+ 
+0

它的工作!谢谢!我甚至没有考虑过使用udfs – dtj

相关问题