gpt4 book ai didi

python - 识别 Postgres 中重复的时间序列

转载 作者:行者123 更新时间:2023-11-29 13:29:55 24 4
gpt4 key购买 nike

我有一个包含列的时间序列表(在 Postgres 数据库中)

item_id,  country_id,  year,  month, value

在此表中有重复的时间序列:它们具有相同的 country_id 和时间序列日期/值,但分配了不同的 item_id,例如:'Red Apples' 和 'Apples, Red'

如何识别这些重复的时间序列?我希望 (country_id, year, month, value) 匹配项目存在的所有日期。

我是初学者,所以请原谅我遗漏的任何细节。我主要是在寻找概念性方法 - 我可以在 Postgres 或 python/Pandas 中实现它。

例如,我希望能够检测到这样的东西:

item_id,     country_id,     year,     month,    value
-------------------------------------------------------
Red Apples 5 1996 1 300
Red Apples 5 1996 2 500
Red Apples 5 1996 3 370
Apples, Red 5 1996 1 300
Apples, Red 5 1996 2 500
Apples, Red 5 1996 3 370

我希望输出看起来像这样:

item_id1,     item_id2,      country_id,     year,     month_range
-----------------------------------------------------------------
Red Apples Apples, Red 5 1996 [1,3]

这样的事情也可以:

item_id1,     item_id2,      country_id,     year,     time_month,   value
--------------------------------------------------------------------------
Red Apples Apples, Red 5 1996 1 300
Red Apples Apples, Red 5 1996 2 500
Red Apples Apples, Red 5 1996 3 370

我想尝试这样的事情:

select distinct A.country_id, A.item_id, B.item_id, A.year, A.month, A.value
from my_table as A,
my_table as B
where
(A.country_id=B.country_id and
A.item_id<>B.item_id and
A.year=B.year and
A.month=B.month and
A.value=B.value )

然后我会检查以确保所有日期/值都出现在每个已识别的 item_id 对中。但如果可能的话,我想一次检查所有日期/值。

我不确定表连接是否合适...?

最佳答案

请查看下面的更新!

除非您提供有关示例数据和预期结果的更多详细信息,否则我认为以下查询可能会有所帮助:

SELECT country_id,  year,  month, value
FROM a_table
GROUP BY country_id, year, month, value
HAVING count(*) > 1;

此查询将显示所有条目,除了 item_id 之外都是相同的。如果您想查找与重复组对应的所有行,请使用此查询:

SELECT item_id, country_id,  year,  month, value
FROM a_table
WHERE (country_id, year, month, value)
IN (
SELECT country_id, year, month, value
FROM a_table
GROUP BY country_id, year, month, value
HAVING count(*) > 1)
ORDER BY country_id, year, month, value, item_id;

我已将 item_id 列设置为排序顺序中的最后一列,这样可以更清楚地识别重复项。随意调整。此查询可能需要一段时间,具体取决于您的数据。

为了避免将来出现这种情况(重复日期),您可能需要创建一个唯一约束,如下所示:

ALTER TABLE a_table ADD CONSTRAIN u_cymv
UNIQUE (country_id, year, month, value);

编辑:添加评论后,我提出了以下查询来查找一系列重复项:

WITH a_table(item_id,country_id,year,month,value) AS (VALUES
('Red Apples'::text,5,1996,1,300::numeric),
('Red Apples',5,1996,2,500),
('Red Apples',5,1996,3,370),
('Apples, Red',5,1996,1,300),
('Apples, Red',5,1996,2,500),
('Apples, Red',5,1996,3,370)
), dups AS (
SELECT string_agg(item_id,'/') AS items,
country_id,value,
daterange(to_date(year::text||month,'YYYYMM'),
(to_date(year::text||month,'YYYYMM')
+INTERVAL'1mon')::date,'[)') AS range
FROM a_table
GROUP BY country_id,year,month,value
HAVING count(*) > 1
)
SELECT grp,count(*),items,country_id,
daterange(min(lower(range)), max(upper(range)), '[)') r,
array_agg(value)
FROM (
SELECT items,country_id,range,value,
sum(g) OVER (ORDER BY country_id, range) grp
FROM (
SELECT items,country_id,
range,value,
CASE WHEN lag(range) OVER (PARTITION BY country_id
ORDER BY range) -|- range
THEN NULL ELSE 1 END g
FROM dups) s
) s
GROUP BY grp,country_id,items
HAVING count(*) >= 3
ORDER BY country_id,r,items;

它的作用:

  1. a_table 是提供的示例数据的副本;
  2. dups 是查找重复记录的工具。我还将 year,month 列转换为 daterange,因为我认为没有其他方法可以正确找到穿越 NY 的系列;
  3. 在列出重复项之后,如果它们不是 adjacent,我会将之前的 range(在 country_id 内)与当前的进行比较, 组标志 g 已设置;
  4. 接下来,我使用 running total effect sum() 函数创建组标识符 grp。对于样本数据,这只产生了一组;
  5. 最后,我使用 grp 作为 GROUP BY 将数据分组到系列中。我还将 country_iditems 包含到 GROUP BY 中,但这只是为了避免将它们包装到聚合函数中——它们在每个 中都是唯一的code>grp 无论如何。我还形成了一个新的 daterange 列,这是因为 range 类型没有内置聚合函数。

在执行此查询之前,您可能需要增加 work_mem,我说过最多 1GB(取决于实际表中的行数)。请试试这个,让我知道它是否适合你。如果您可以为此分享EXPLAIN(分析,缓冲区),那就太好了。

关于python - 识别 Postgres 中重复的时间序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26366248/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com