2017-04-22 68 views
3

如何選擇在Scala中具有特定索引的數據框的所有列?根據列索引選擇Spark Dataframe

例如,如果一個數據幀有100列,我想只提取列(10,12,13,14,15),如何做到這一點?

下面選擇從數據幀df其在陣列colNames提到的列名的所有列:

df = df.select(colNames.head,colNames.tail: _*) 

如果有類似,其中有

colNos = Array(10,20,25,45) 

colNos陣列我如何改造超過df.select只能提取特定索引處的那些列。

回答

5

可以mapcolumns

import org.apache.spark.sql.functions.col 

df.select(colNos map df.columns map col: _*) 

或:

df.select(colNos map (df.columns andThen col): _*) 

或:

df.select(colNos map (col _ compose df.columns): _*) 

所有上述所示的方法是等價的,不徵收性能損失。下面的映射:

colNos map df.columns 

只不過是當地Array接入(constant time access for each index)和StringColumn之間進行選擇的基礎變種select不影響執行計劃:

val df = Seq((1, 2, 3 ,4, 5, 6)).toDF 

val colNos = Seq(0, 3, 5) 

df.select(colNos map df.columns map col: _*).explain 
== Physical Plan == 
LocalTableScan [_1#46, _4#49, _6#51] 
df.select("_1", "_4", "_6").explain 
== Physical Plan == 
LocalTableScan [_1#46, _4#49, _6#51] 
2

@ user6910411上面的回答工作就像魅力一樣,任務/邏輯計劃的數量與我下面的方法類似。 但是我的方法有點快。
因此,
我建議你去與column names而不是column numbersColumn names更安全多得多比使用numbers。您可以採用如下方案:

val colNames = Seq("col1", "col2" ...... "col99", "col100") 

val selectColNames = Seq("col1", "col3", .... selected column names ...) 

val selectCols = selectColNames.map(name => df.col(name)) 

df = df.select(selectCols:_*) 

如果你正在猶豫寫的所有100個名,然後有一個快捷的方法太

val colNames = df.schema.fieldNames