如何 "negative select" 火花数据框中的列
How to "negative select" columns in spark's dataframe
我想不通,但猜想很简单。我有一个火花数据框 df。此 df 包含列 "A"、"B" 和 "C"。现在假设我有一个包含此 df 的列名称的数组:
column_names = Array("A","B","C")
我想以这种方式做一个 df.select()
,我可以指定哪些列 而不是 到 select。
示例:假设我不想 select 列 "B"。我试过了
df.select(column_names.filter(_!="B"))
但这不起作用,因为
org.apache.spark.sql.DataFrame
cannot be applied to (Array[String])
所以,here 它说它应该与 Seq 一起使用。然而,尝试
df.select(column_names.filter(_!="B").toSeq)
结果
org.apache.spark.sql.DataFrame
cannot be applied to (Seq[String]).
我做错了什么?
好吧,这很丑陋,但是这个快速火花 shell 会话显示了一些有用的东西:
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. The signature of select is there to ensure your list of selected columns is not empty – which makes the conversion from the list of selected columns to varargs 中处理得有点复杂。
Since Spark 1.4 you can use 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]
可以按照下面的方式做
它利用 Spark 的能力 select 使用正则表达式的列。
并使用否定的前瞻表达式 ?!
在这种情况下,dataframe 包含列 a、b、c 和正则表达式,但不包括列表中的列 b。
注意:您需要使用 spark.sql.parser.quotedRegexColumnNames
=true
会话设置为列名查找启用正则表达式。并且需要 Spark 2.3+
select `^(?!b).*`
from (
select 1 as a, 2 as b, 3 as c
)
val columns = Seq("A","B","C")
df.select(columns.diff(Seq("B")))
我遇到了同样的问题并通过这种方式解决了(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
在 pyspark 中你可以做到
df.select(list(set(df.columns) - set(["B"])))
使用多条线也可以
cols = df.columns
cols.remove("B")
df.select(cols)
对于 Spark v1.4 及更高版本,使用 drop(*cols)
-
Returns 没有指定列的新 DataFrame。
例子-
df.drop('age').collect()
对于 Spark v2.3 及更高版本,您也可以使用 colRegex(colName)
-
根据指定为正则表达式的列名称选择列,returns 将其指定为 Column。
示例-
df = spark.createDataFrame([("a", 1), ("b", 2), ("c", 3)], ["Col1", "Col2"])
df.select(df.colRegex("`(Col1)?+.+`")).show()
对于旧版本的 Spark,获取数据框中的列列表,然后删除要从中删除的列(可能使用设置操作),然后使用 select
选择结果列表。
我想不通,但猜想很简单。我有一个火花数据框 df。此 df 包含列 "A"、"B" 和 "C"。现在假设我有一个包含此 df 的列名称的数组:
column_names = Array("A","B","C")
我想以这种方式做一个 df.select()
,我可以指定哪些列 而不是 到 select。
示例:假设我不想 select 列 "B"。我试过了
df.select(column_names.filter(_!="B"))
但这不起作用,因为
org.apache.spark.sql.DataFrame cannot be applied to (Array[String])
所以,here 它说它应该与 Seq 一起使用。然而,尝试
df.select(column_names.filter(_!="B").toSeq)
结果
org.apache.spark.sql.DataFrame cannot be applied to (Seq[String]).
我做错了什么?
好吧,这很丑陋,但是这个快速火花 shell 会话显示了一些有用的东西:
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. The signature of select is there to ensure your list of selected columns is not empty – which makes the conversion from the list of selected columns to varargs 中处理得有点复杂。
Since Spark 1.4 you can use 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]
可以按照下面的方式做
它利用 Spark 的能力 select 使用正则表达式的列。
并使用否定的前瞻表达式 ?!
在这种情况下,dataframe 包含列 a、b、c 和正则表达式,但不包括列表中的列 b。
注意:您需要使用 spark.sql.parser.quotedRegexColumnNames
=true
会话设置为列名查找启用正则表达式。并且需要 Spark 2.3+
select `^(?!b).*`
from (
select 1 as a, 2 as b, 3 as c
)
val columns = Seq("A","B","C")
df.select(columns.diff(Seq("B")))
我遇到了同样的问题并通过这种方式解决了(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
在 pyspark 中你可以做到
df.select(list(set(df.columns) - set(["B"])))
使用多条线也可以
cols = df.columns
cols.remove("B")
df.select(cols)
对于 Spark v1.4 及更高版本,使用 drop(*cols)
-
Returns 没有指定列的新 DataFrame。
例子-
df.drop('age').collect()
对于 Spark v2.3 及更高版本,您也可以使用 colRegex(colName)
-
根据指定为正则表达式的列名称选择列,returns 将其指定为 Column。
示例-
df = spark.createDataFrame([("a", 1), ("b", 2), ("c", 3)], ["Col1", "Col2"])
df.select(df.colRegex("`(Col1)?+.+`")).show()
对于旧版本的 Spark,获取数据框中的列列表,然后删除要从中删除的列(可能使用设置操作),然后使用 select
选择结果列表。