PySpark Dataframes:如何使用紧凑的代码在多个条件下进行过滤



如果我有一个列名称列表,并且我想对这些列的值大于零的行进行过滤,我可以做类似的事情吗?

columns = ['colA','colB','colC','colD','colE','colF']
new_df = df.filter(any([df[c]>0 for c in columns]))

这回报:

ValueError:无法将列转换为bool:请使用'&'代替'and',在构建DataFrame布尔值时,'|'表示'or', '~'表示'not'表达式

我想我可以把这些列和过滤器加在一列上(因为我没有负数)。但如果我有,和式就行不通了。不管怎样,如果我必须在不同于求和的条件下过滤这些列,我该怎么做呢?任何想法?

您可以使用or_操作符:

from operator import or_
from functools import reduce
newdf = df.where(reduce(or_, (df[c] > 0 for c in df.columns)))

EDIT:更多pythonista解决方案:

from pyspark.sql.functions import lit
def any_(*preds):
    cond = lit(False)
    for pred in preds:
        cond = cond | pred
    return cond
newdf = df.where(any_(*[df[c] > 0 for c in df.columns]))

EDIT 2:完整示例:

Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _ / _ / _ `/ __/  '_/
   /__ / .__/_,_/_/ /_/_   version 2.1.0-SNAPSHOT
      /_/
Using Python version 3.5.1 (default, Dec  7 2015 11:16:01)
SparkSession available as 'spark'.
In [1]: from pyspark.sql.functions import lit
In [2]: %pas
%paste     %pastebin  
In [2]: %paste
def any_(*preds):
    cond = lit(False)
    for pred in preds:
        cond = cond | pred
    return cond
## -- End pasted text --
In [3]: df = sc.parallelize([(1, 2, 3), (-1, -2, -3), (1, -1, 0)]).toDF()
In [4]: df.where(any_(*[df[c] > 0 for c in df.columns])).show()
# +---+---+---+
# | _1| _2| _3|
# +---+---+---+
# |  1|  2|  3|
# |  1| -1|  0|
# +---+---+---+
In [5]: df[any_(*[df[c] > 0 for c in df.columns])].show()
# +---+---+---+
# | _1| _2| _3|
# +---+---+---+
# |  1|  2|  3|
# |  1| -1|  0|
# +---+---+---+
In [6]: df.show()
# +---+---+---+
# | _1| _2| _3|
# +---+---+---+
# |  1|  2|  3|
# | -1| -2| -3|
# |  1| -1|  0|
# +---+---+---+

相关内容

  • 没有找到相关文章