在Java中将字符串数组的数组转换为字符串数组的spark数据帧

问题描述

我正在尝试将string[][]转换为由Dataset<Row>组成的string[]列。 我在线浏览了文档和可用示例,但找不到与此类似的内容。我不知道它是否可行,因为我是Spark的完整入门者。

样本输入:
String[][] test = {{"test1"},{"test2","test3"},{"test4","test5"}};
样本输出

Dataset<Row> test_df
test_df.show()
+-------------+
|          foo|
+-------------+
|      [test1]|
|[test2,test3]|
|[test4,test5]|
+-------------+

我可能为string [] []定义了structType错误,我也尝试了不同的方法。 这是我想要做的:


    String[][] test = {{"test1"},"test5"}};
    
    List<String[]> test1 = Arrays.asList(test);
    
    StructType structType = DataTypes.createStructType(
        DataTypes.createStructField(
                   "foo",DataTypes.createArrayType(DataTypes.StringType),true));
    
    Dataset<Row> t = spark.createDataFrame(test1,structType);
    t.show();

解决方法

您的代码存在问题,因为您试图使用一种方法(spark.createDataFrame(List<Row>,StructType)),该方法需要一个Row对象的列表。但是,您可以将它与数组列表一起使用。

有几种方法可以克服它:

  • 从每个数组创建一个Row,然后应用您一直在使用的方法。
  • 使用bean编码器创建字符串数组的数据集,然后使用行编码器将其转换为Row的数据集。
  • 使用Java Bean创建数据框。

我认为最后一种方法是最简单的,因此这里是您的操作方法。您必须定义一个小的Java Bean,其唯一的实例变量是String数组。

public static class ArrayWrapper {
    private String[] foo;

    public ArrayWrapper(String[] foo) {
        this.foo = foo;
    }

    public String[] getFoo() {
        return foo;
    }

    public void setFoo(String[] foo) {
        this.foo = foo;
    }
}

确保Java Bean具有一个接受String数组的构造函数。

然后,要创建数据框,首先要从数组数组中创建一个ArrayWrapper(您的Java Bean)列表,然后使用createDataFrame(List<?>,Class<?>)方法创建一个数据框。

String[][] test = {{"test1"},{"test2","test3"},{"test4","test5"}};
List<ArrayWrapper> list = Arrays.stream(test).map(ArrayWrapper::new).collect(Collectors.toList());
Dataset<Row> testDF = spark.createDataFrame(list,ArrayWrapper.class);
testDF.show();

列的名称由Java Bean中实例变量的名称确定。