Scala 基于列索引的Spark数据帧选择
如何选择在Scala中具有特定索引的数据帧的所有列 例如,如果一个数据帧有100列,而我只想提取列10、12、13、14、15,那么如何进行同样的操作 下面选择dataframe df中的所有列,该列的列名在数组colNames中提到:Scala 基于列索引的Spark数据帧选择,scala,apache-spark,dataframe,apache-spark-sql,Scala,Apache Spark,Dataframe,Apache Spark Sql,如何选择在Scala中具有特定索引的数据帧的所有列 例如,如果一个数据帧有100列,而我只想提取列10、12、13、14、15,那么如何进行同样的操作 下面选择dataframe df中的所有列,该列的列名在数组colNames中提到: df = df.select(colNames.head,colNames.tail: _*) 如果有类似的,colNos数组 colNos = Array(10,20,25,45) 如何转换上述df.select以仅获取特定索引处的列。您可以映射到列: 导
df = df.select(colNames.head,colNames.tail: _*)
如果有类似的,colNos数组
colNos = Array(10,20,25,45)
如何转换上述df.select以仅获取特定索引处的列。您可以映射到列:
导入org.apache.spark.sql.functions.col
df.selectcolNos映射df.columns映射col:_*
或:
df.selectcolNos映射df.columns和then col:_*
或:
df.selectcolNos映射列uu组合df.columns:_*
上述所有方法都是等效的,不会造成性能损失。以下映射:
colNos map df.columns
只是本地数组访问,在基于字符串或基于列的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
==实际计划==
LocalTableScan[_146,_449,_651]
df.选择_1、_4、_6.解释
==实际计划==
LocalTableScan[_146,_449,_651]
@上面user6910411的回答很有魅力,任务数量/逻辑计划与下面的方法类似。但我的方法要快一点。 所以 我建议您选择列名而不是列号。列名比使用数字更安全、更轻巧。您可以使用以下解决方案:
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
示例:使用Scala按索引获取Spark Dataframe的前14列
你不能简单地像我那样尝试,但失败了:
// Gives array of names by index (first 14 cols for example)
val sliceCols = df.columns.slice(0, 14)
// Maps names & selects columns in dataframe
val subset_df = df.select(sliceCols)
原因是您必须将Array[String]的数据类型转换为Array[org.apache.spark.sql.Column],以便切片工作
或者使用Currying high five将其包装到函数中,以便:
// Subsets Dataframe to using beg_val & end_val index.
def subset_frame(beg_val:Int=0, end_val:Int)(df: DataFrame): DataFrame = {
val sliceCols = df.columns.slice(beg_val, end_val)
return df.select(sliceCols.map(name => col(name)):_*)
}
// Get first 25 columns as subsetted dataframe
val subset_df:DataFrame = df_.transform(subset_frame(0, 25))
// Subsets Dataframe to using beg_val & end_val index.
def subset_frame(beg_val:Int=0, end_val:Int)(df: DataFrame): DataFrame = {
val sliceCols = df.columns.slice(beg_val, end_val)
return df.select(sliceCols.map(name => col(name)):_*)
}
// Get first 25 columns as subsetted dataframe
val subset_df:DataFrame = df_.transform(subset_frame(0, 25))