Spark - Scala - 根据条件从数据框中删除列

时间:2017-06-06 09:29:37

标签: scala apache-spark

我们有一个特定的需求,其中我必须dropdataframe列,该列中只有一个唯一值。以下是我们正在做的事情

val rawdata = spark.read.format("csv").option("header","true").option("inferSchema","true").load(filename)

随后在所有列中查找唯一值,我们使用spark

中支持的HyperLog++算法
val cd_cols  = rawdata.select(rawdata.columns.map(column => approxCountDistinct(col(column)).alias(column)): _*)

输出

scala> cd_cols.show
+----+----------+---------+---+---------+--------------+---------+----------+----------------+---------+--------------+-------------+
|  ID|First Name|Last Name|Age|Attrition|BusinessTravel|DailyRate|Department|DistanceFromHome|Education|EducationField|EmployeeCount|
+----+----------+---------+---+---------+--------------+---------+----------+----------------+---------+--------------+-------------+
|1491|       172|      154| 43|        2|             3|      913|         3|              30|        1|             6|            1|
+----+----------+---------+---+---------+--------------+---------+----------+----------------+---------+--------------+-------------+

请注意,我有两列,其中1为唯一值。我想创建另一个dataframe,其中包含除了这两列(EducationEmployeeCount)之外的所有列

我尝试使用for循环,但不是很开心也尝试了

cd_cols.columns.filter(colName => cd_cols.filter(colName) <= 1)

这也无效。

请问有更聪明的方法吗。

由于

巴拉

2 个答案:

答案 0 :(得分:1)

您尝试以下命令:

RecyclerView.Adapter

在这里,我们首先获取df.selectExpr(df.first().getValuesMap[Int](df.columns).filter(_._2 != 1).keys.toSeq: _*).show 的第一行,然后使用dataframe将其转换为地图,并使用列名称,只过滤值不为1的列。

答案 1 :(得分:0)

如果你想继续你最初的尝试,下面的内容也应该有效。此外,请注意,使用Spark 2.0以后,您可以将列表传递给drop并删除那些列。对于你正在做的事情,这可能会更清楚。

或者最坏的情况是另一种方式。

这适用于大多数火花版本。

    val keptCols: Seq[Column] = df.columns
      .map(c => (c, df.select(c).first.getLong(0)))
      .filter{case (c, v) => v!=1}
      .map{case (c, v) => df(c)}
      .toSeq

    df.select(keptCols: _*).show

对于&gt; Spark 2.0

    val droppedCols: Seq[String] = df.columns
      .map(c => (c, df.select(c).first.getLong(0)))
      .filter{case (c, v) => v==1}
      .map{case (c, v) => c}
      .toSeq

    df.drop(droppedCols: _*).show

两者都应该使用相同的结果。