Как столбцы "отрицательного выбора" в блоке данных искры

Я не могу понять это, но думаю, это просто. У меня есть световой блок данных 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 немного сложнее.

Ответ 4

val columns = Seq("A","B","C")

df.select(columns.diff(Seq("B")))

Ответ 6

В pyspark вы можете сделать

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

Используя более одной строки, вы также можете сделать

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

Ответ 7

//selectWithout позволяет указать, какие столбцы пропустить:

df.selectWithout("B")