使用Postgresql查找值集群

使用Postgresql查找值集群,postgresql,Postgresql,考虑以下示例表: CREATE TABLE rndtbl AS SELECT generate_series(1, 10) AS id, random() AS val; 我想为每个id找到一个cluster\u id,这样簇之间的距离至少为0.1。我如何计算这样的集群分配 一个具体的例子是: select * from rndtbl ; id | val ----+------------------- 1 | 0.485714662820101 2 | 0.

考虑以下示例表:

CREATE TABLE rndtbl AS
SELECT
  generate_series(1, 10) AS id,
  random() AS val;
我想为每个
id
找到一个
cluster\u id
,这样簇之间的距离至少为0.1。我如何计算这样的集群分配

一个具体的例子是:

select * from rndtbl ;
 id |        val
----+-------------------
  1 | 0.485714662820101
  2 | 0.185201027430594
  3 | 0.368477711919695
  4 | 0.687312887981534
  5 | 0.978742253035307
  6 | 0.961830694694072
  7 |  0.10397826647386
  8 | 0.644958863966167
  9 | 0.912827260326594
 10 | 0.196085536852479
(10 rows)
结果将是:
id
s(2,7,10)在一个集群中,而(5,6,9)在另一个集群中,而(4,8)在另一个集群中,以及(1)和(3)作为单态集群

SELECT * FROM rndtbl ;
┌────┬────────────────────┐
│ id │        val         │
├────┼────────────────────┤
│  1 │  0.153776332736015 │
│  2 │  0.572575284633785 │
│  3 │  0.998213059268892 │
│  4 │  0.654628816060722 │
│  5 │  0.692200613208115 │
│  6 │  0.572836415842175 │
│  7 │ 0.0788379465229809 │
│  8 │  0.390280921943486 │
│  9 │  0.611408909317106 │
│ 10 │  0.555164183024317 │
└────┴────────────────────┘
(10 rows)
使用
LAG
窗口功能了解当前行是否在新的集群中:

SELECT *, val - LAG(val) OVER (ORDER BY val) > 0.1 AS new_cluster
FROM rndtbl ;
┌────┬────────────────────┬─────────────┐
│ id │        val         │ new_cluster │
├────┼────────────────────┼─────────────┤
│  7 │ 0.0788379465229809 │ (null)      │
│  1 │  0.153776332736015 │ f           │
│  8 │  0.390280921943486 │ t           │
│ 10 │  0.555164183024317 │ t           │
│  2 │  0.572575284633785 │ f           │
│  6 │  0.572836415842175 │ f           │
│  9 │  0.611408909317106 │ f           │
│  4 │  0.654628816060722 │ f           │
│  5 │  0.692200613208115 │ f           │
│  3 │  0.998213059268892 │ t           │
└────┴────────────────────┴─────────────┘
(10 rows)
最后,您可以对
true
(仍按
val
排序)的数量进行
SUM
以获得行的集群(从0开始计数):

使用
LAG
窗口功能了解当前行是否在新的集群中:

SELECT *, val - LAG(val) OVER (ORDER BY val) > 0.1 AS new_cluster
FROM rndtbl ;
┌────┬────────────────────┬─────────────┐
│ id │        val         │ new_cluster │
├────┼────────────────────┼─────────────┤
│  7 │ 0.0788379465229809 │ (null)      │
│  1 │  0.153776332736015 │ f           │
│  8 │  0.390280921943486 │ t           │
│ 10 │  0.555164183024317 │ t           │
│  2 │  0.572575284633785 │ f           │
│  6 │  0.572836415842175 │ f           │
│  9 │  0.611408909317106 │ f           │
│  4 │  0.654628816060722 │ f           │
│  5 │  0.692200613208115 │ f           │
│  3 │  0.998213059268892 │ t           │
└────┴────────────────────┴─────────────┘
(10 rows)
最后,您可以对
true
(仍按
val
排序)的数量进行
SUM
以获得行的集群(从0开始计数):


在Postgres中可能有一种方法可以做到这一点,但就个人而言,我更愿意使用像R这样的工具来做数据科学方面的工作,它有很多包来处理这类问题。在Postgres中可能有一种方法可以做到这一点,但就个人而言,我更愿意使用像R这样的工具来做数据科学方面的工作,它有很多包来处理这类问题。