如何"否定选择" spark的数据框中的列

时间:2015-07-15 15:36:36

标签: scala apache-spark dataframe apache-spark-sql

我无法弄明白,但猜测它很简单。我有一个火花数据帧df。这个df有列" A"," B"和" C"。现在让我们说我有一个包含此df列的名称的数组:

column_names = Array("A","B","C")

我想以这样的方式做df.select(),我可以指定要选择的 列。 示例:让我们说我不想选择列" B"。我试过了

df.select(column_names.filter(_!="B"))

但这不起作用,如

  

org.apache.spark.sql.DataFrame    无法应用于(Array [String])

所以,here它说它应该与Seq一起使用。但是,尝试

df.select(column_names.filter(_!="B").toSeq)

结果

  

org.apache.spark.sql.DataFrame    不能应用于(Seq [String])。

我做错了什么?

9 个答案:

答案 0 :(得分:35)

Since Spark 1.4您可以使用drop方法:

<强> Scala的

case class Point(x: Int, y: Int)
val df = sqlContext.createDataFrame(Point(0, 0) :: Point(1, 2) :: Nil)
df.drop("y")

<强>的Python

df = sc.parallelize([(0, 0), (1, 2)]).toDF(["x", "y"])
df.drop("y")
## DataFrame[x: bigint]

答案 1 :(得分:7)

我遇到了同样的问题并以这种方式解决了(oaffdf是一个数据帧):

val dropColNames = Seq("col7","col121")
val featColNames = oaffdf.columns.diff(dropColNames)
val featCols = featColNames.map(cn => org.apache.spark.sql.functions.col(cn))
val featsdf = oaffdf.select(featCols: _*)

https://forums.databricks.com/questions/2808/select-dataframe-columns-from-a-sequence-of-string.html

答案 2 :(得分:5)

好吧,这很难看,但这个快速的火花贝壳会话显示了一些有用的东西:

scala> val myRDD = sc.parallelize(List.range(1,10))
myRDD: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[17] at parallelize at <console>:21

scala> val myDF = myRDD.toDF("a")
myDF: org.apache.spark.sql.DataFrame = [a: int]

scala> val myOtherRDD = sc.parallelize(List.range(1,10))
myOtherRDD: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[20] at parallelize at <console>:21

scala> val myotherDF = myRDD.toDF("b")
myotherDF: org.apache.spark.sql.DataFrame = [b: int]

scala> myDF.unionAll(myotherDF)
res2: org.apache.spark.sql.DataFrame = [a: int]

scala> myDF.join(myotherDF)
res3: org.apache.spark.sql.DataFrame = [a: int, b: int]

scala> val twocol = myDF.join(myotherDF)
twocol: org.apache.spark.sql.DataFrame = [a: int, b: int]

scala> val cols = Array("a", "b")
cols: Array[String] = Array(a, b)

scala> val selectedCols = cols.filter(_!="b")
selectedCols: Array[String] = Array(a)

scala> twocol.select(selectedCols.head, selectedCols.tail: _*)
res4: org.apache.spark.sql.DataFrame = [a: int]

other SO questions中处理对需要一个函数的函数varargs。 select的签名是为了确保您所选列的列表不为空 - 这使得从所选列的列表转换为varargs更加复杂。

答案 3 :(得分:1)

FirstName = FirstName.value;
LastName = LastName.value;
Adress = Adress.value;
for(i = 0; i < 10; i++) {
    contacts[i] = [FirstName, LastName, Adress];
}

答案 4 :(得分:1)

在pyspark你可以做到

df.select(list(set(df.columns) - set(["B"])))

使用多行也可以

cols = df.columns
cols.remove("B")
df.select(cols)

答案 5 :(得分:0)

可以通过[SPARK-12139]针对Hive查询的REGEX列规范进行操作

https://issues.apache.org/jira/browse/SPARK-12139

答案 6 :(得分:0)

对于 Spark v1.4 及更高版本,请使用 drop(*cols) -

返回没有指定列的新DataFrame。

示例-

df.drop('age').collect()

对于 Spark v2.3 及更高版本,您也可以使用 colRegex(colName) -

根据指定为正则表达式的列名称选择列,并将其返回为Column

示例-

df = spark.createDataFrame([("a", 1), ("b", 2), ("c",  3)], ["Col1", "Col2"])
df.select(df.colRegex("`(Col1)?+.+`")).show()

参考-colRegexdrop


对于旧版本的Spark,请获取数据框中的列列表,然后从中删除要删除的列(也许使用set操作),然后使用select选择结果列表。

答案 7 :(得分:0)

您快到了:只需将过滤后的数组映射到col,然后使用: _*解压缩列表即可:

df.select(column_names.filter(_!="B").map(col): _*)

答案 8 :(得分:-3)

// selectWithout允许您指定要省略的列:

db.collection.updateOne({
    gameID: 900000001,
    "characters.characterID": 1
},
{
    $push: {
        "characters.$.inventory": {
             $each:["item2", "item3"]
        }
    }
})