【问题标题】:how to select columns from list dynamically in dataframe plus a fixed column如何在数据框中动态地从列表中选择列以及固定列
【发布时间】:2020-07-10 22:02:01
【问题描述】:

我在 java8 中使用 spark-sql-2.4.1v。

我有动态列列表被传递到我的函数中。

List<String> cols = Arrays.asList("col_1","col_2","col_3","col_4");
Dataset<Row> df = //which has above columns plus "id" ,"name" plus many other columns;

需要选择cols + "id" + "name"

我的做法如下

Dataset<Row> res_df = df.select("id", "name", cols.stream().toArray( String[]::new)); 

这导致编译错误。那么如何处理这个用例。

试过了:

当我执行以下操作时:

List<String> cols = new ArrayList<>(Arrays.asList("col_1","col_2","col_3","col_4"));
cols.add("id");
cols.add("name");

给出错误

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)

【问题讨论】:

  • 你得到UnsupportedOperationException,因为你使用的List的实际类型是Arrays.ArrayList(从Arrays.asList返回)而不是util.ArrayList

标签: java dataframe apache-spark apache-spark-sql


【解决方案1】:

你有很多方法可以实现这一点,依赖于不同的select 方法签名。

一种可能的解决方案,假设cols List 是不可变的并且不受您的代码控制:

import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import scala.collection.JavaConverters;

public class ATest {
    public static void main(String[] args) {
        SparkSession spark = SparkSession
                .builder()
                .appName("Java Spark SQL basic example")
                .master("local[2]")
                .getOrCreate();

        List<String> cols = Arrays.asList("col_1", "col_2");

        Dataset<Row> df = spark.sql("select 42 as ID, 'John' as NAME, 1 as col_1, 2 as col_2, 3 as col_3, 4 as col4");
        df.show();

        ArrayList<String> newCols = new ArrayList<>();
        newCols.add("NAME");
        newCols.addAll(cols);
        df.select("ID", JavaConverters.asScalaIteratorConverter(newCols.iterator()).asScala().toSeq())
                .show();
    }
}

【讨论】:

  • @BdEngineer 我已经用一个完整的工作示例更新了帖子。
【解决方案2】:

您可以创建 Columns 数组并将其传递给 select 语句。

import org.apache.spark.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

List<String> cols = new ArrayList<>(Arrays.asList("col_1","col_2","col_3","col_4"));
cols.add("id");
cols.add("name");
Column[] cols2 = cols.stream()
        .map(s->new Column(s)).collect(Collectors.toList())
        .toArray(new Column[0]);

settingsDataset.select(cols2).show();

【讨论】:

  • 尝试将 List 更改为 ArrayList cols 并添加这些导入 import java.util.ArrayList; import java.util.Arrays; import java.util.List;
猜你喜欢
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 2019-11-25
  • 2019-03-04
  • 2016-07-15
  • 2016-09-09
相关资源
最近更新 更多