【问题标题】:Apply logical operator on a list in pyspark在 pyspark 中的列表上应用逻辑运算符
【发布时间】:2021-11-20 11:28:51
【问题描述】:

我必须在 pyspark 的 where 函数中的条件列表上应用逻辑运算符 or。在 pyspark 中,or 的运算符是 |,它无法使用 Python 中的 any() 函数。有没有人建议如何解决这个问题?

下面是一个简单的例子:

# List of conditions
spark_conditions = [cond1, cond2, ..., cond100]

# Apply somehow the '|' operator on `spark_conditions`
# spark_conditions would look like -> [cond1 | cond2 | .... | cond100]

df.select(columns).where(spark_conditions)

感谢您的帮助,谢谢!

【问题讨论】:

    标签: python dataframe apache-spark pyspark


    【解决方案1】:

    我认为这实际上是一个熊猫问题,因为spark.sql.DataFrame 似乎至少表现得像熊猫数据框。但我不知道火花。无论如何,您的“火花条件”实际上是(我认为)布尔系列。我确信有一些方法可以正确地对 pandas 中的布尔系列求和,但您也可以像这样减少它:

    import pandas as pd
    from funtools import reduce
    
    df = pd.DataFrame([0,1,2,2,1,4], columns=["num"])
    filter1 = df["num"] > 3
    filter2 = df["num"] == 2
    filter3 = df["num"] == 1
    filters = (filter1, filter2, filter3)
    filter = reduce(lambda x, y: x | y, filters)
    df.filter(filter) # note .where is an alias for .filter
    

    它的工作原理是这样的:reduce() 在过滤器中获取前两个东西并在它们上运行lambda x, y: x | y。然后它获取that 的输出,并将其作为x 传递给lambda x, y: x | y,获取filters 中的第三个​​ 条目并将其作为y 传递。它一直持续到它没有任何东西可以采取为止。

    因此,最终效果是沿可迭代对象累积应用函数。在这种情况下,该函数只返回其输入的|,因此它完全按照您手动操作的方式执行,但如下所示:

    (filter1 | filter2) | filter3
    

    我怀疑有一种更熊猫或更闪亮的方式来做到这一点,但 reduce 有时值得拥有。 Guido doesn't like it though.

    【讨论】:

    • ...也适用于火花条件!
    • 是的,reduce(fn, iterable) 模式适用于任何事情:您只需将fn 应用于可迭代对象。我将更新答案以解释它是如何工作的。我认为 spark.sql.DataFrame 是 spark 已扩展的 pandas DataFrame(因此声称这是一个 pandas 问题),但也许它们只是具有类似的界面。我会让答案不那么教条。
    【解决方案2】:

    2e0byoanswer 非常正确。我正在添加另一种如何在 pyspark 中完成此操作的方法。

    如果我们的条件是 SQL 条件表达式的字符串(例如 col_1 == 'ABC101'),我们可以组合所有这些字符串并将该组合字符串作为条件提供给 where()(或 filter())。

    df = spark.createDataFrame([(1, "a"),
                                (2, "b"),
                                (3, "c"),
                                (4, "d"),
                                (5, "e"),
                                (6, "f"),
                                (7, "g")], schema="id int, name string")
    condition1 = "id == 1"
    condition2 = "id == 4"
    condition3 = "id == 6"
    conditions = [condition1, condition2, condition3]
    combined_or_condition = " or ".join(conditions)     # Combine the conditions: condition1 or condition2 or condition3
    df.where(combined_or_condition).show()
    

    " or ".join(conditions) 通过使用or 作为分隔符/连接器/组合器连接conditions 中存在的所有字符串来创建一个字符串。在这里,combined_or_condition 变为 id == 1 or id == 4 or id == 6

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 2018-12-18
      相关资源
      最近更新 更多