Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spark-Scala-根据条件从数据帧中删除列_Scala_Apache Spark - Fatal编程技术网

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

Spark-Scala-根据条件从数据帧中删除列,scala,apache-spark,Scala,Apache Spark,我们有一个特殊的需求,在这个需求中,我必须从一个只有一个唯一值的dataframe中删除列。下面是我们正在做的 val rawdata = spark.read.format("csv").option("header","true").option("inferSchema","true").load(filename) 随后,为了在所有列中找到唯一的值,我们使用spark中支持的HyperLog++算法 val cd_cols = rawdata.select(rawdata.colum

我们有一个特殊的需求,在这个需求中,我必须从一个只有一个唯一值的
dataframe
中删除
列。下面是我们正在做的

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
,它包含除这两列之外的所有列(
Education
EmployeeCount

我尝试使用for循环,但不太高兴,也尝试了

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

cd_cols.columns.filter(colName=>cd_cols.filter(colName)您可以尝试以下命令:

df.selectExpr(df.first().getValuesMap[Int](df.columns).filter(_._2 != 1).keys.toSeq: _*).show

这里,我们首先获取
数据帧的第一行
,并使用
getValueMap
和列名将其转换为一个映射,然后只过滤值不是1的列。

如果您想从最初尝试的内容继续进行,以下操作也应该有效。另外,请注意,在Spark 2.0之后,您可以将列表传递到drop并以这种方式删除列。这可能会更清楚地了解您正在做什么

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

这应该适用于大多数spark版本

    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
对于>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

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

如果您不想要这些列,那么只需选择其余的列。@RameshMaharjan,我现在还不知道。这完全取决于上一条语句返回的唯一值。我无法对这些列进行“硬编码”。这意味着您要删除那些有1个值的列?@RameshMaharjan是的。删除只有一个唯一值的列是真的吗?通过查看一行,我们可以知道要删除哪些列?我的意思是说,如果一行中的一列为1,那么该特定列中的所有其他行都将为1,这是对称的吗?这很有魅力。我必须做的一个小更正是将[Int]改为[Long].val select_cols=df.selectExpr(df.first().getValuesMap[Long](df.columns).filter(u._2!=1).keys.toSeq:*)非常感谢您的帮助什么是u._2?这是列名吗?u.2是元组的第二个元素