如何在Java中的Spark中将String映射到Seq <string>

时间:2018-12-28 12:54:44

标签: apache-spark apache-spark-mllib

我想使用自己的令牌生成器对存储为Dataset<String>的文本进行令牌化,并获取Dataset<Seq<String>>(以便可以将其传递给CountVectorizer)。

预期的输入(/tmp/fulltext.txt):

t1 t2 t3
t4 t5

预期输出:

[t1, t2, t3]
[t4, t5]

我写的令牌生成器是(基本上现在做的事与Spark附带的Tokenizer相同,但是我需要重写它以支持中文文本的令牌化,因此我不能使用官方的{ {1}}):

Tokenizer

我要制作的Spark应用程序是

public class Utils {

  public static Seq<String> segment(String text) {
    String[] array = text.split(" ");
    List<String> tokens = new ArrayList<>();
    for (String term : array) {
      tokens.add(term.toLowerCase());
    }
    return JavaConverters
        .asScalaIteratorConverter(tokens.iterator())
        .asScala()
        .toSeq();
  }

}

我是Spark的初学者,上面的代码正是我认为可以使用的代码(在阅读了官方指南之后)。但是事实证明public class TokenizeTest { public static void main(String[] args) { SparkSession spark = SparkSession .builder() .appName("Tokenize Test") .getOrCreate(); Dataset<String> rawText = spark .read() .textFile("/tmp/fulltext.txt") .cache(); Encoder<Seq> listEncoder = Encoders.bean(Seq.class); // Compilation error Dataset<Seq<String>> newText = rawText .map((MapFunction<String, Seq<String>>) s -> Utils.segment(s), listEncoder); newText.show(); spark.stop(); } } 的代码根本没有编译。您认为有办法解决此问题吗?

1 个答案:

答案 0 :(得分:2)

使用这样的Scala集合将无法正常工作。一次Seq与Bean不兼容,第二次它是通用的。

如果要拆分,只需使用segement定义为的数组:

public class Utils {

  public static String[] segment(String text) {
    return text.split(" ");
  }

}

TokenizeTest定义为:

public class TokenizeTest {

  public static void main(String[] args) {

    SparkSession spark = SparkSession
        .builder()
        .appName("Tokenize Test")
        .getOrCreate();

    Dataset<String> rawText = spark
        .read()
        .textFile("/path/to/file")
        .cache();

    Encoder<String []> listEncoder = spark.implicits().newStringArrayEncoder();


    Dataset<String []> newText = rawText
        .map((MapFunction<String, String []>) s -> Utils.segment(s), listEncoder);

    newText.show();
    spark.stop();
  }
}

在实践中,您可以考虑使用org.apache.spark.sql.functions.splitorg.apache.spark.ml.feature.Tokenizer而不是重新发明轮子。