当前位置: 首页 > 知识库问答 >
问题:

Pyspark udf在条件定义中返回一列,接受几列作为输入

梁勇
2023-03-14

我使用的是spark 2.1,用法是pyscripting

问题陈述:有一个场景,需要传递多个列作为输入,并返回一列作为输出

a b c

S S S

S NS NS

S NS S

S S NS

新南威尔士州

我的输出必须如下所示

a b c d

S S S S

S NS NS NS

S NS S S

S,S,NS,NS

NS S NS NS

我试图注册一个UDF来传递这3列[a, b, c]作为输入并返回d列作为输出这里a, b, c, d是列名

我发现很难获得输出。下面是使用的语法

def return_string(x):
      if [x.a=='s' & x.b=='S' & x.c=='s']
          return 'S'
      else if[x.a=='s' & x.b=='NS' & x.c=='s']
          return 'S'
      else if[x.a=='s' & x.b=='S' & x.c=='NS']
          return 'NS;

func= udf(returnstring,types.StringType())

有人能帮我完成这个逻辑吗?

共有2个答案

许俊贤
2023-03-14

它应该是:

@udf
def return_string(a, b, c):
    if a == 's' and b == 'S' and c == 's':
        return 'S'
    if a == 's' and b == 'NS' and c == 's':
        return 'S'
    if a == 's' and b == 'S' and c == 'NS':
        return 'NS'

df = sc.parallelize([('s', 'S', 'NS'), ('?', '?', '?')]).toDF(['a', 'b', 'c'])

df.withColumn('result', return_string('a', 'b', 'c')).show()
## +---+---+---+------+
## |  a|  b|  c|result|
## +---+---+---+------+
## |  s|  S| NS|    NS|
## |  ?|  ?|  ?|  null|
## +---+---+---+------+
  • 应列出所有参数(除非您将数据作为结构传递)。
  • 您应该使用而不是

就我个人而言,我会跳过所有ifs并使用简单的cript

@udf
def return_string(a, b, c):
    mapping = {
        ('s', 'S', 's'): 'S',
        ('s', 'NS' 's'): 'S',
        ('s', 'S', 'NS'): 'NS',
    }
    return mapping.get((a, b, c))

根据您的要求调整条件。

总的来说,您应该更喜欢Steven Laan提供的优秀答案中所示的SQL表达式(您可以在(…,…).when(…,……)中使用<code>链接多个条件)。

柴飞扬
2023-03-14

我试图使用内置的< code>withColumn和< code>when函数来实现:

from pyspark.sql.functions import col, when, lit

df.withColumn('d', when(
     ((col('A') == 'S') & (col('B') == 'S') & (col('C')=='S'))
   | ((col('A') == 'S') & (col('B') == 'NS') & (col('C')=='S'))
 , lit('S')
 ).otherwise(lit('NS'))
).show()

这也是假设这两个值是相互排斥的(因此反之亦然

 类似资料:
  • 问题内容: 这是问题的简化:我有一个看起来像这样的选择: 并返回的数据快照看起来像这样 我想做的是,如果工作组是内部的,则选择不显示受让人的名称。而是显示工作流。 因此,例如,我想要实现的结果将是这样的: 我希望这是有道理的?基本上是一个条件选择,可以检测某个列是否包含某个值,然后用[whatever]替换另一个列的值。 提前致谢! 编辑我想实现这样的事情: 问题答案: 您没有提到您的DBMS,但

  • 问题内容: 我有一个功能。,它接受一个整数并返回True或False。 我有10个整数的列表。我想返回列表中的第一个项目(与原始列表的顺序相同),该项目已返回True。 尽可能地Python。 问题答案: next(x for x in lst if matchCondition(x)) 应该可以,但是如果列表中的所有元素都不匹配,它将提高。您可以通过提供第二个参数来抑制这种情况: 如果没有匹配项

  • 工作在SQL服务器 我有三张桌子 [TESTDB]。[dbo]。[TestList]数据看起来像 [路由]。[dbo]。[WUList]数据看起来像 [路由]。[dbo]。[WUArea]数据看起来像 我已经能够将[TestList]加入到[UWARE]或[WUList]我需要的数据显示方式,但我无法以我需要的方式加入3个列表。 并不是每个TestID都出现在[WUList]或[WUArea] 如

  • 我有一个包含以下列名的dataframe(对于引用,我只提到了一行)。我希望获得中的最大size_cd。在本例中,具有最大值,即24。我想将列名称中的数字作为返回值返回。 输入数据帧: 必需输出:即后面的部分(因为此列具有最大值) 我将感谢您对此的反馈。

  • 我用的是spark 2.1,脚本是pyspark。请帮我一下,因为我被困在这里了。 问题陈述:根据多列的条件创建新列 输入<code>数据帧<code>如下 现在我需要创建一个新列作为FLG,我的条件是如果

  • 我有这个数据 如果M3大于UCL,MM3将为“UP”,否则为“NULL” 但是我有几个M列(比如m1~m1005),所以我想做一些代码,比如mutate_each和mutate_at。如何使用mutate和ifelse函数在特定条件下创建新列?