【问题标题】:How to verify an array contain another array如何验证一个数组是否包含另一个数组
【发布时间】:2019-10-22 13:17:18
【问题描述】:

我有一个包含 4 列的 pyspark 数据框。

示例数据框:

id                       |  name                          | age |  job
    -------------------------------------------------------------------
     ["98475", "748574"] |  ["98475",748574]              |
    -------------------------------------------------------------------
      ["75473","98456"]  |   ["98456"]                    |
    -------------------------------------------------------------------
      ["23456","28596"]  |   ["84758","56849","86954"]      
    -------------------------------------------------------------------

我想比较两列(array<string> types)

例子:

Array_A (id)  | Array_B(name)
------------------------------

如果 Array_B 中的所有值都匹配,则 Array_A 中的值 ==> ok

如果 Array_B 中的所有值都在 array_A ==> 介质中

如果 Array_B 的值在 array_A 中不存在 ==> 未找到

我做了一个 UDF:

def contains(x,y):
        z = len(set(x) - set(y))
        if ((z == 0) & (set(x) == set(y))):
            return "ok"
        elif (set(y).isin(set(x))) & (z != 0):
            return "medium"
        else set(y) != set(x):
            return "not found in raw"


contains_udf = udf(contains)

然后:

new_df= df.withColumn(
    "new_column",
    F.when(
        (df.id.isNotNull() & df.name.isNotNull()),
        contains_udf(df.id,df.name)
    ).otherwise(
        F.lit(None)
    )

)

我收到了这个错误:

else set(y) != set(x):
           ^
SyntaxError: invalid syntax

如何使用 udf 或其他解决方案(如 array_contains)来解决它? 谢谢

【问题讨论】:

  • else前面不需要条件。也许您的意思是elif set(y) != set(x) 如果您使用集合,最好使用集合属性,如.issubset.issupersetdocs.python.org/3.8/library/stdtypes.html#frozenset.issubset
  • 如果您使用的是 spark 2.4+ 版,则不需要udf。你可以使用array_intersect
  • @pault 我正在使用 spark 2.2 请帮忙。谢谢
  • @verojoucla 对我提供的解决方案有帮助吗?
  • @Sid 我收到此错误 TypeError: 'NoneType' object is not iterable

标签: python apache-spark pyspark


【解决方案1】:

正如@Buckeye14Guy 和@Sid 指出代码中的主要问题,您可能还需要清理一些逻辑:

from pyspark.sql.functions import udf

def contains(x,y): 
  try:
    sx, sy = set(x), set(y) 
    if len(sy) == 0: 
        return 'list is empty'
    elif sx == sy: 
        return "ok"    
    elif sy.issubset(sx): 
        return "medium"  
    # below none of sy is in sx
    elif sx - sy == sx: 
        return "none found in raw"  # including empty x
    else: 
        return "some missing in raw"
  # in exception, for example `x` or `y` is None (not a list)
  except:
    return "not an iterable or other errors"

udf_contains = udf(contains, 'string')

df.withColumn('new_column', udf_contains('id', 'name')).show(truncate=False)
+---------------+---------------------+-----------------+
|id             |name                 |new_column       |
+---------------+---------------------+-----------------+
|[98475, 748574]|[98475, 748574]      |ok               |
|[75473, 98456] |[98456]              |medium           |
|[23456, 28596] |[84758, 56849, 86954]|none found in raw|
+---------------+---------------------+-----------------+

【讨论】:

    【解决方案2】:
    else set(y) != set(x):
               ^
    SyntaxError: invalid syntax
    

    这是因为else 语句不需要条件。它包含仅在不满足先前条件时才执行的代码。改为使用:

    elif set(y) != set(x):
        #code
    

    else :
        #code
    

    【讨论】:

    • 只有在使用import set 时才会出现该错误。删除该行。
    • set 不是一个模块——它是一个对象类型。无需导入。
    猜你喜欢
    • 2017-05-30
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2015-10-28
    • 1970-01-01
    相关资源
    最近更新 更多