Dataframe 如何添加一个条件,当数据帧有某个列时,只添加相应的;什么时候;条件

Dataframe 如何添加一个条件,当数据帧有某个列时,只添加相应的;什么时候;条件,dataframe,apache-spark,apache-spark-sql,Dataframe,Apache Spark,Apache Spark Sql,我正在使用spark-sql-2.4.1v和java8。 我有一个场景,我需要在列iff上添加一个when条件,该列存在于相应的数据帧中。怎样才能做到呢 例: //这里的问题是,有时df可能不包含/fetch“x”列 然后它应该在结果_df中给出“y”值。但是在上面 此时df中不存在将错误作为“x”列抛出的语句 重点 那么,如何检查列(即“x”)是否在 concat()否则与其余列(即“y”)一起使用 此处也可能出现相反的情况,即df中仅出现col(x),但 非列(“y”)。在某些情况下,df中

我正在使用spark-sql-2.4.1v和java8。 我有一个场景,我需要在列iff上添加一个when条件,该列存在于相应的数据帧中。怎样才能做到呢

例:

//这里的问题是,有时df可能不包含/fetch“x”列 然后它应该在结果_df中给出“y”值。但是在上面 此时df中不存在将错误作为“x”列抛出的语句 重点

那么,如何检查列(即“x”)是否在 concat()否则与其余列(即“y”)一起使用

此处也可能出现相反的情况,即df中仅出现col(x),但 非列(“y”)。在某些情况下,df中的x列和y列都可用 那么它工作得很好

问题。 当列出现在数据框中时,如何在when子句中添加条件

有问题的一次更正。 如果没有柱,我不应该进入“带柱”状态

例:

如果出现第x列:

如果出现第x列:

如果x列和y列同时出现:


您需要使用您的语言本机流控制来实现这一点,例如在python/PySpark中使用if、else语句

原因是Spark df函数在列上工作,因此无法应用.when()条件检查列名称,它只查看列中的值,并按行应用逻辑/条件

例如,对于F.when(col(x)=col(y)),spark将把它转换为Java,在Java中,它将在两个col中应用该逻辑rowise

如果您认为Spark dfs是由行对象组成的,那么这也是有意义的,因此它所做的是将条件发送到驱动器,以便将此条件应用于每个对象(行),看起来像这样[row(x=2),row(y=5)]

仅当x和y都存在时才需要应用操作,就好像只有一个存在一样。无论如何,它将返回带有现有x或y列的df

我会应用类似于上面的东西,“另存为”功能以实现可重用性

当()仅为符合条件的concat值时,这将为您提供一个col,其中包含符合条件的concat值

df.when('concat_col', F.when( F.col('age') < F.lit('18'), 
                      concat(F.col('name'), F.lit('_underAge'))
                      .otherwise(F.col('name'),F.lit('_notUnderAge')))
df.when('concat_col',F.when(F.col('age')

希望这有帮助!

您需要使用您的语言本机流控制来实现这一点,例如在python/Pypark中使用if、else语句

原因是Spark df函数在列上工作,因此无法应用.when()条件检查列名称,它只查看列中的值,并按行应用逻辑/条件

例如,对于F.when(col(x)=col(y)),spark将把它转换为Java,在Java中,它将在两个col中应用该逻辑rowise

如果您认为Spark dfs是由行对象组成的,那么这也是有意义的,因此它所做的是将条件发送到驱动器,以便将此条件应用于每个对象(行),看起来像这样[row(x=2),row(y=5)]

仅当x和y都存在时才需要应用操作,就好像只有一个存在一样。无论如何,它将返回带有现有x或y列的df

我会应用类似于上面的东西,“另存为”功能以实现可重用性

当()仅为符合条件的concat值时,这将为您提供一个col,其中包含符合条件的concat值

df.when('concat_col', F.when( F.col('age') < F.lit('18'), 
                      concat(F.col('name'), F.lit('_underAge'))
                      .otherwise(F.col('name'),F.lit('_notUnderAge')))
df.when('concat_col',F.when(F.col('age')

希望这有帮助!

您可以通过使用
columns
属性和简单的if Scala/Java语句动态创建列列表来实现这一点。该列表应包括
targetColumn
,具体取决于在数据帧架构(Scala代码)中是否找到列:

import org.apache.spark.sql.functions.{col,concat_ws}
//我们应该检查的列。根据您的要求更改此列,即“y”
val targetColumn=“x”
var concatItems=序列(列(“y”))
//如果在df.columns中找到,则添加targetColumn
if(df.columns.contains(targetColumn))
concatItems=concatItems:+col(targetColumn)
df.withColumn(“新列”,当(列(“abc”)=“a”,连接项:”))
请注意,我们使用
contact
而不是
contact
,因为当
contactItems
包含一个或多个项目并分别应用
分隔符时,它会自动检查

更新:

以下是使用
select
语句更新的新代码:

var selectExpr=null
if(df.columns.contains(“x”)和&df.columns.contains(“y”))
selectExpr=Seq(
当(列(“abc”)==“a”,列(“x”)。作为(“新x”),
当(列(“abc”)==“a”,列(“y”)。作为(“新y”),
当(列(“abc”)==“a”,concat_ws(“x”),列(“y”)。作为(“新的x”)
)
else if(df.columns.contains(“y”))
选择expr=when(列(“abc”)==“a”,列(“y”)。作为(“新y”)
其他的
选择expr=when(列(“abc”)==“a”,列(“x”)。作为(“新的x”)
df.select(selectExpr:*)

请注意,我们不需要使用
with column
select
正是您的案例所需要的。

您可以通过使用
columns
属性和简单的if Scala/Java语句动态创建列列表来实现这一点。该列表应包括或不包括
targetColumn
,具体取决于在dataframe架构中是否找到列(scala代码):

import org.apache.spark.sql.functions.{col,concat_ws}
//我们应该检查的列。根据您的要求更改此列,即“y”
val targetColumn=“x”
var concatItems=序列(列(“y”))
//如果找到,则添加targetColumn
val result_df =  df
                  .withColumn("new_y", when(col("abc") === "a" , concat(col("y"))))
val result_df =  df
               .withColumn("new_x", when(col("abc") === "a" , concat(col("x"))))
                .withColumn("new_y", when(col("abc") === "a" , concat(col("y"))))
                  .withColumn("new_x_y", when(col("abc") === "a" , concat(col("x"),lit("_"),col("y"))))
def check_columns(df, col_x, col_y, concat_name):
    '''
    df: spark dataframe
    col_x & col_y: the two cols to concat if both present
    concat_name: name for new concated col
    -----------------------------------------------------
    returns: df with new concated col if oth x & y cols present
    otherwise if returns df with x or y col if only on present 
    '''
    cols = list(col_x) + list(col_y)
    if all(item in df.columns for item in cols) 
    df = df.withColumn(concat_name, concat(col(col_x),lit("_"),col(col_y)))
    return df
df.when('concat_col', F.when( F.col('age') < F.lit('18'), 
                      concat(F.col('name'), F.lit('_underAge'))
                      .otherwise(F.col('name'),F.lit('_notUnderAge')))