Как отфильтровать символ @ в кортеже типа (String, Seq (String, String, ...))? - PullRequest
0 голосов
/ 13 июня 2019

Я пытаюсь найти всех упомянутых людей внутри твитов. Для этого мне нужно отфильтровать слова, которым предшествует '@' внутри твитов.

Я использую Java 8 с Spark 2.4.3.

Во-первых, я загружаю свой JSON-файл как RDD[Tweet] (в упражнении специально указывается работа с RDD, а не с DataFrame).

Tweet - это класс case следующим образом:

case class Tweet (
    id : String,
    user : String,
    userName : String,
    text : String,
    place : String,
    country : String,
    lang : String
)

Далее я создаю пары (пользователь, твиты) и разделяю слова в твиттах по "":

val tweets = loadData
val persons = tweets.map(row => (row.user, Seq(row.text.split(" ").mkString(","))))

Затем я попытался flatMap все и перебрать все элементы, чтобы найти "@", но у меня ничего не получилось.

Я ожидаю, что результаты будут следующими:

(user1, Seq(@michael, @jean, @paul, @charles))
(user2, Seq(@kol, @louis))

Ответы [ 2 ]

0 голосов
/ 13 июня 2019

Используйте регулярное выражение, чтобы отфильтровать все слова, начинающиеся с @, но имеющие ровно один @, а затем символы

val persons = tweets.map(row => (row.user, Seq(row.text.split(" ").filter(_.matches("^@{1}.*")).mkString(","))))
0 голосов
/ 13 июня 2019

Пожалуйста, проверьте это:

//Input tweet data  
   scala> df.show(false)
    +---+--------+-------------+-----------------------------------+-------+-------+--------+
    |Id |User    |UserName     |Text                               |Place  |Country|language|
    +---+--------+-------------+-----------------------------------+-------+-------+--------+
    |1  |nksuthar|Nikhil Suthar|Good Morning @nikhil and @hardik   |Mumbai |India  |Hindi   |
    |2  |matt    |Mathew       |Welcome @John                      |Paris  |France |English |
    |3  |JohnM   |Johnson      |@Mathew Are you coming with @nguyen|NewYork|US     |English |
    +---+--------+-------------+-----------------------------------+-------+-------+--------+

    //Create one UDF to check '@' in Text

    scala> val check_@ = (s:String) => {
                val ss = s.split(" ").filter(x => x.contains("@"))
                ss.toSeq}

    //Register UDF as filtreUDF

    scala> val filterUdf = udf(check_@)

    scala> val newdf  = df.withColumn("new_col", filterUdf(col("Text")))

    /*
    +---+--------+-------------+-----------------------------------+-------+-------+--------+------------------+
    |Id |User    |UserName     |Text                               |Place  |Country|language|new_col           |
    +---+--------+-------------+-----------------------------------+-------+-------+--------+------------------+
    |1  |nksuthar|Nikhil Suthar|Good Morning @nikhil and @hardik   |Mumbai |India  |Hindi   |[@nikhil, @hardik]|
    |2  |matt    |Mathew       |Welcome @John                      |Paris  |France |English |[@John]           |
    |3  |JohnM   |Johnson      |@Mathew Are you coming with @nguyen|NewYork|US     |English |[@Mathew, @nguyen]|
    +---+--------+-------------+-----------------------------------+-------+-------+--------+------------------+
    */
    scala> val finaltpl = newdf.select("User","new_col").rdd.map(x => (x.get(0), x.get(1)))

    scala> finaltpl.foreach(println)
    (matt,WrappedArray(@John))
    (JohnM,WrappedArray(@Mathew, @nguyen))
    (nksuthar,WrappedArray(@nikhil, @hardik))
...