【问题标题】:How to create a Row from a List or Array in Spark using java如何使用 java 从 Spark 中的列表或数组创建行
【发布时间】:2017-02-03 10:01:03
【问题描述】:

在 Java 中,我使用 RowFactory.create() 创建一个 Row:

Row row = RowFactory.create(record.getLong(1), record.getInt(2), record.getString(3));

其中“记录”是来自数据库的记录,但我无法提前知道“记录”的长度,所以我想使用列表或数组来创建“行”。在 Scala 中,我可以使用 Row.fromSeq() 从 List 或 Array 创建 Row,但如何在 Java 中实现呢?

【问题讨论】:

    标签: java apache-spark apache-spark-mllib


    【解决方案1】:

    我不确定我是否正确地回答了您的问题,但您可以使用 RowFactory 从 java 中的 ArrayList 创建 Row。

    List<MyData> mlist = new ArrayList<MyData>();
        mlist.add(d1);
        mlist.add(d2);
    
    Row row = RowFactory.create(mlist.toArray());   
    

    【讨论】:

    • 你好,当我使用你的方法时,我发现spark将mlist视为一个整体对象:Row row = RowFactory.create(mlist);System.out.println("row number:" + row.length());System.out.println("mlist number:" + mlist.size());我得到:row number:1 mlist number:2
    • 是的,但是 Row 会有两条记录。您可以尝试打印 System.out.println("row number:" + row.toSeq());
    • 嗨,非常感谢!你可以试试这个: Object[] rowArray = {obj1, obj2, ....} Row row = RowFactory.create(rowArray); System.out.println("行号:" + row.length());你会得到 - 行号:6
    • 谢谢。我更新了我的答案。我检查了 RowFactory 和 GenericRow 类的源代码。-“使用对象数组作为底层存储的内部行实现。”
    【解决方案2】:

    我们经常需要在现实世界的应用程序中创建数据集或数据框。以下是如何在 Java 应用程序中创建行和数据集的示例:

    // initialize first SQLContext
    SQLContext sqlContext = ... 
    StructType schemata = DataTypes.createStructType(
            new StructField[]{
                    createStructField("NAME", StringType, false),
                    createStructField("STRING_VALUE", StringType, false),
                    createStructField("NUM_VALUE", IntegerType, false),
            });
    Row r1 = RowFactory.create("name1", "value1", 1);
    Row r2 = RowFactory.create("name2", "value2", 2);
    List<Row> rowList = ImmutableList.of(r1, r2);
    Dataset<Row> data = sqlContext.createDataFrame(rowList, schemata);
    
    +-----+------------+---------+
    | NAME|STRING_VALUE|NUM_VALUE|
    +-----+------------+---------+
    |name1|      value1|        1|
    |name2|      value2|        2|
    +-----+------------+---------+
    

    【讨论】:

    • @thank you,在 scala 中我们会做 sc.parallize(List((x,y),(a,b))).toDF("col1","col2"),它是这么简单,为什么要使用这些 Row、JavaRDD 等?有什么简单的方法吗?
    • 您是说您需要在现实世界的应用程序中创建数据集并对所有变量进行硬定义。没有任何意义。在现实世界中,一切都必须是可参数化的,并且事先您不知道这些值。
    【解决方案3】:

    对于简单的列表值,您可以使用Encoders

     List<Row> rows = ImmutableList.of(RowFactory.create(new Timestamp(currentTime)));
     Dataset<Row> input = sparkSession.createDataFrame(rows, Encoders.TIMESTAMP().schema());
    

    【讨论】:

      【解决方案4】:

      //创建一个DTO列表

      List<MyDTO> dtoList = Arrays.asList(.....));
      

      //创建DTO的数据集

      Dataset<MyDTO> dtoSet = sparkSession.createDataset(dtoList,
                      Encoders.bean(MyDTO.class));
      

      //如果需要Row的数据集

      Dataset<Row> rowSet= dtoSet .select("col1","col2","col3");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-17
        • 2017-09-12
        • 2020-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多