根据 PostgreSQL 中的频率获取日期的单词排名

Posted

技术标签:

【中文标题】根据 PostgreSQL 中的频率获取日期的单词排名【英文标题】:Get ranking of words over date based on frequency in PostgreSQL 【发布时间】:2021-03-28 22:25:18 【问题描述】:

我有一个存储 twitter 数据的数据库:

        Create Table tweet(
            ID BIGINT UNIQUE,
            user_ID BIGINT,
            created_at TIMESTAMPTZ,
            tweet TEXT;

我正在尝试编写一个查询,该查询通过 tweet 中的所有行获取每个单词的频率,并返回前十个最常见的单词以及单词在每个日期的排名。

例子:

("word1":[1,20,22,23,24,25,26,27,28,29,30,29,28,27,26,25,26,27,28,29,30,29,28,29,28,27,28,29,30,30,...],
'word2' [...])

我当前的查询获得了前十个单词,但我在获取这些单词每天的排名时遇到了一些问题。

当前查询:

    SELECT word, count(*)
    FROM (
        SELECT regexp_split_to_table(
            regexp_replace(tweet_clean, '\y(rt|co|https|amp|f)\y', '', 'g'), '\s+')
        AS word
    FROM tweet
    ) t
    GROUP BY word
    ORDER BY count(*) DESC
    LIMIT 10;

返回:

[('vaccine', 286669),
 ('covid', 213857),
 ('yum', 141345),
 ('pfizer', 39532),
 ('people', 28960),
 ('beer', 27117),
 ('say', 24569),
 ('virus', 23682),
 ('want', 21988),
 ('foo', 19823)]

【问题讨论】:

您可以使用rank()dense_rank()获取排名。 【参考方案1】:

如果您想要每天前 10 名,您可以这样做:

select *
from (
    select date_trunc('day', created_at) as created_day, word, count(*) as cnt,
        rank() over(partition by date_trunc('day', created_at) order by count(*) desc) rn
    from tweet t
    cross join lateral regexp_split_to_table(
        regexp_replace(tweet_clean, '\y(rt|co|https|amp|f)\y', '', 'g'),
        '\s+'
    ) w(word)
    group by created_day, word
) t
where rn <= 10
order by created_day, rn desc

【讨论】:

【参考方案2】:

如果我理解正确,最常用的单词需要 10 行。然后你想要一个频率数组。假设每天都使用每个单词,应该这样做:

select wd.word,
       array_agg(day_rank) over (order by created_day) as ranks
from (select date_trunc('day', t.created_at) as created_day, w.word,
             sum(count(*)) as total_cnt,
             rank() over(partition by date_trunc('day', created_at) order by count(*) desc) as day_rank
      from tweet t cross join lateral
           regexp_split_to_table(regexp_replace(tweet_clean, '\y(rt|co|https|amp|f)\y', '', 'g'
                                               ), '\s+'
                                ) w(word)
      group by created_day, word
     ) wd
order by total_cnt desc
limit 10;

这里的挑战是数组可以有不同的长度。在 Postgres 中,您可以添加附加值——但不清楚应该在其中放置什么来进行排名。

问题在于排名是每天。所以,考虑两天,一天有 100 个单词,一天有 10 个单词。首先,“10”的排名是非常高的排名。第二个10的排名很低。

如果您需要帮助解决它,我可能会建议您考虑一下这个问题并提出一个新问题

【讨论】:

感谢您的回答。我在运行您的查询时收到一个错误:psycopg2.errors.SyntaxError: syntax error at or near "over" LINE 3: array_agg(day_rank over order by created_day) as rank... @mehsheenman 。 . .糟糕,缺少一些括号。

以上是关于根据 PostgreSQL 中的频率获取日期的单词排名的主要内容,如果未能解决你的问题,请参考以下文章

3-2 从单词中获取单词出现的频率信息,并把他们写进对应的列表里

如何从Postgresql中的工作日编号中获取日期名称?

从频率词典中获取字数和平均长度

我如何根据姓名、数字、金钱、日期等对文本中的单词进行分类?

Postgresql 生成日期系列(性能)

根据频率创建音频文件