Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 基于列索引的Spark数据帧选择_Scala_Apache Spark_Dataframe_Apache Spark Sql - Fatal编程技术网

Scala 基于列索引的Spark数据帧选择

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以仅获取特定索引处的列。您可以映射到列: 导

如何选择在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以仅获取特定索引处的列。

您可以映射到列:

导入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))