Как столбцы "отрицательного выбора" в блоке данных искры
Я не могу понять это, но думаю, это просто. У меня есть световой блок данных 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])
Итак, здесь говорится, что он должен работать с Seq вместо этого. Однако, пытаясь
df.select(column_names.filter(_!="B").toSeq)
приводит к
org.apache.spark.sql.DataFrame не может применяться к (Seq [String]).
Что я делаю неправильно?
Ответы
Ответ 1
Начиная с 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]
Ответ 2
ОК, это уродливо, но этот сеанс быстрой световой оболочки показывает что-то, что работает:
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]
Предоставляет varargs функции, которая требует одного, обрабатывается в других вопросах SO. Подпись select - это то, что ваш список выбранных столбцов не пуст, что делает преобразование из списка выбранных столбцов в varargs немного сложнее.
Ответ 3
У меня была та же проблема и она была решена таким образом (oaffdf - это dataframe):
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
Ответ 4
val columns = Seq("A","B","C")
df.select(columns.diff(Seq("B")))
Ответ 5
Можно будет сделать через [SPARK-12139] Спецификация столбца REGEX для запросов на улей
https://issues.apache.org/jira/browse/SPARK-12139
Ответ 6
В pyspark вы можете сделать
df.select(list(set(df.columns) - set(["B"])))
Используя более одной строки, вы также можете сделать
cols = df.columns
cols.remove("B")
df.select(cols)
Ответ 7
//selectWithout позволяет указать, какие столбцы пропустить:
df.selectWithout("B")