代码之家  ›  专栏  ›  技术社区  ›  Ged

检查Spark数据帧行是否有任何列满足条件,并在找到第一个这样的列时停止

  •  0
  • Ged  · 技术社区  · 7 年前

    以下代码可用于筛选包含值1的行。图像中有很多列。

    import org.apache.spark.sql.types.StructType
    
    val df = sc.parallelize(Seq(
       ("r1", 1, 1),
       ("r2", 6, 4),
       ("r3", 4, 1),
       ("r4", 1, 2)
       )).toDF("ID", "a", "b")
    
    val ones = df.schema.map(c => c.name).drop(1).map(x => when(col(x) === 1, 1).otherwise(0)).reduce(_ + _)
    
    df.withColumn("ones", ones).where($"ones" === 0).show
    

    这里的缺点是,理想情况下,当第一个这样的条件得到满足时,它应该停止。即找到的第一列。好吧,我们都知道。

    但是如果不使用自定义项或非常具体的逻辑,我就找不到一个优雅的方法来实现这一点。地图将处理所有列。

    0 回复  |  直到 7 年前
        1
  •  1
  •   Ged    5 年前

    df
      .withColumn("ones", df.columns.tail.map(x => when(col(x) === 1, true)
      .otherwise(false)).reduceLeft(_ or _))
      .where(!$"ones")
      .show()
     
    

    但我不确定spark是否支持短路,我想不是( https://issues.apache.org/jira/browse/SPARK-18712

    因此,也可以使用lazy对行应用自定义函数 exist 在斯卡拉的 Seq :

    df
      .map{r => (r.getString(0),r.toSeq.tail.exists(c => c.asInstanceOf[Int]==1))}
      .toDF("ID","ones")
      .show()
    

    这种方法类似于自定义项,因此不确定您是否接受这种方法。

    推荐文章