запрос pyspark и запрос sql pyspark - PullRequest
1 голос
/ 21 июня 2020

эй, у меня есть фрейм данных, который содержит строки с этими столбцами: дата и текст, и мне нужно найти, сколько строк содержит слово «корона» в день (двухсторонние фреймы данных и sql)

  • слово «корона» должно быть словом, а не подстрокой, и если рядом со словом стоит знак пунктуации, мне тоже нужно его посчитать. текстовый столбец, затем я добавил столбец индикатора, призванный отметить, есть ли в строке слово корона, после чего я просуммировал столбец проверки и сгруппировал столбец даты

    1, и я хотел спросить, правильно ли это способ сделать это?

    2. я попытался перевести это в pyspark sql запрос (мне нужно добавить контрольный столбец с кодом sql, если я использую этот способ), но результаты были очень разными, так как я могу это перевести?

    dataframes way:
    #above i defiend the puntuation function and i read the data into df
    df = df.withColumn('no_punc_text',punc_udf('text'))
    df = df.select('no_punc_text','dates')
    df.registerTempTable('my_table')
    df = df.withColumn("check",F.col("no_punc_text").rlike("corona " or " corona" or " corona 
        ").cast("Integer"))
            dfway = df.groupBy("dates").sum('check')
    the sql way:
    sqlw = spark.sql(
          """
            select dates, sum(
             case when (no_punc_text rlike ' corona') then 1 
             when (no_punc_text rlike ' corona') then 1 
             when (no_punc_text rlike ' corona ') then 1 else 0 end
            ) as check
            from my_table group by dates
          """)
    

Ответы [ 2 ]

1 голос
/ 21 июня 2020

используйте границу слова (\b), как показано ниже -

Загрузите тестовые данные

  val df = Seq("corona", "corona?", "this is corona", "coronavirus", "corona's", "is this corona?")
      .toDF("text")
      .withColumn("dates", monotonically_increasing_id())
    df.show(false)
    df.printSchema()

    /**
      * +---------------+-----+
      * |text           |dates|
      * +---------------+-----+
      * |corona         |0    |
      * |corona?        |1    |
      * |this is corona |2    |
      * |coronavirus    |3    |
      * |corona's       |4    |
      * |is this corona?|5    |
      * +---------------+-----+
      *
      * root
      * |-- text: string (nullable = true)
      * |-- dates: long (nullable = false)
      */

обнаружите коронное слово согласно приведенным ниже требованиям

слово corona должно быть словом, а не подстрокой, и если рядом со словом стоит знак пунктуации, мне тоже нужно это посчитать.

    df.createOrReplaceTempView("my_table")
    spark.sql(
      """
        | select dates, sum(
        |         case when (text rlike '\\bcorona\\b') then 1
        |         else 0 end
        |        ) as check
        |        from my_table group by dates
      """.stripMargin)
      .show(false)

    /**
      * +-----+-----+
      * |dates|check|
      * +-----+-----+
      * |2    |1    |
      * |4    |1    |
      * |5    |1    |
      * |0    |1    |
      * |1    |1    |
      * |3    |0    |
      * +-----+-----+
      */

Обратите внимание, что coronavirus строка не определяется как корона, так как вы не хотите рассматривать подстроку

In python

sqlw = spark.sql(
      """
         select dates, sum(
          case when (text rlike '\\bcorona\\b') then 1
          else 0 end
         ) as check
         from my_table group by dates
      """)
0 голосов
/ 21 июня 2020

Я могу помочь с частью pyspark. Лучше избегать использования udf, всегда есть эквивалентный способ сделать это с помощью функции inbuit. В вашем случае будет полезна функция столбца contains (). Обратитесь: https://spark.apache.org/docs/latest/api/python/pyspark.sql.html?highlight=contain#pyspark. sql .Column.contains

Рассмотрим тестовый фрейм данных.

test_df= sqlContext.createDataFrame(["stay safe","lets make the world coronafree","corona spreads through contact","there is no vaccine yet for corona,but is in progress","community has to unite against corona."],"string").toDF('text')
test_df.show(truncate=False)    

+-----------------------------------------------------+
|text                                                 |
+-----------------------------------------------------+
|stay safe                                            |
|lets make the world coronafree                       |
|corona spreads through contact                       |
|there is no vaccine yet for corona,but is in progress|
|community has to unite against corona.               |
+-----------------------------------------------------+

test_df_f = test_df.where(F.col('text').contains('corona'))
test_df_f.show()
+-----------------------------------------------------+
|text                                                 |
+-----------------------------------------------------+
|lets make the world coronafree                       |
|corona spreads through contact                       |
|there is no vaccine yet for corona,but is in progress|
|community has to unite against corona.               |
+-----------------------------------------------------+

вы можете видеть, что все знаки препинания уже приняты во внимание . С помощью этого отфильтрованного фрейма данных, test_df_f, вы можете выполнить подсчет, чтобы напрямую получить количество строк или любое другое агрегирование по дате для дальнейшего анализа.

Если вам нужно сопоставить все слово, вы можете использовать это:

test_df_f_whole = test_df.where("text RLIKE '\\\\bcorona\\\\b'")
test_df_f_whole.show(truncate=False)

+-----------------------------------------------------+
|text                                                 |
+-----------------------------------------------------+
|corona spreads through contact                       |
|there is no vaccine yet for corona,but is in progress|
|community has to unite against corona.               |
+-----------------------------------------------------+

Ссылка: https://html.developreference.com/article/12239248/How+to+use+word+boundary+in+RLIKE+in+PySpark+SQL+Dataframes

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...