Rtree实现对带半径的点聚类

news/2024/7/7 21:15:35

业务上碰到了需要对圆做聚类的场景
sklearn现在的聚类方法dbscan(支持自定义距离公式,但是性能影响巨大
kdtree(不支持自定义距离计算
google、百度无果

思考用rtree实现

参考:

https://zhuanlan.zhihu.com/p/62639268

计算过程

# 数据构建
num_points = 200000
centers = 200
center_box = (0, 300000)
random_state = 4

# 生成样本数据
rng = np.random.default_rng(random_state)
data = rng.uniform(low=center_box[0], high=center_box[1], size=(num_points, 2))
y1 = rng.integers(low=0, high=centers, size=num_points)

# 添加半径数据
r = rng.random(size=num_points) * 10
points = np.column_stack((data, r))
# 距离计算
def distance_with_radius(point1, point2):
    # point1和point2分别为点的坐标和半径,例如 [x1, y1, r1], [x2, y2, r2]
    x1, y1, r1 = point1
    x2, y2, r2 = point2
    dist = np.sqrt((x1 - x2)**2 + (y1 - y2)**2)  # 计算欧氏距离
    return dist - r1 - r2  # 减去半径之和
# 建树
p = index.Property()
p.dimension = 2
idx = index.Index(properties=p)
for i, (x, y, r) in enumerate(points):
    idx.insert(i, (x - r, y - r, x + r, y + r))

# 圆形聚类
clusters = []
defect_clusters = []

# 类似dbscan,访问过的不再计算
visited = set()

for i in range(num_points):
    if i not in visited:
        cluster = []
        defect_cluster = []
        stack = [i]
        while stack:
            point = stack.pop()
            visited.add(point)
            cluster.append(point)
            x, y, r = points[point]
            # 在这里我算了两个eps 45和25
            results = idx.intersection((x - r - 45, y - r - 45, x + r + 45, y + r + 45))
            for j in results:
            	# 计算考虑半径的距离
                distance = distance_with_radius(points[point], points[j])
                if j not in visited and distance <= 45:
                    if distance <= 25:
                        defect_cluster.append(point)
                    stack.append(j)
        clusters.append(cluster)
# 输出聚类结果
num_clusters = len(clusters)
print("聚类数量:", num_clusters)

labels_cluster = np.full(num_points, -1)
labels_defect = np.full(num_points, -1)
n = 1
for cluster in clusters:
    if len(cluster) > 1:
        labels_cluster[[idx for idx in cluster]] = n
        n += 1

n = 1
for cluster in defect_clusters:
    if len(cluster) > 1:
        labels_defect[[idx for idx in cluster]] = n
        n += 1
        
print(labels_cluster)
print(labels_defect)

相较于dbscan加自定义距离公式快了不止一倍
同理,kd-tree也可用同样的方式


http://lihuaxi.xjx100.cn/news/1284947.html

相关文章

360手机打开USB调试+文件传输

360手机USB调试文件传输[用户版] 参考&#xff1a;360手机-360刷机360刷机包twrp、root 360刷机包360手机刷机&#xff1a;360rom.github.io 【前言】 *360手机USB调试 &#xff0c;必须提前打开“开发者模式USB调试”进行 【操作流程】 打开&#xff1a;开发者模式、USB调…

python3D绘制评估优化算法性能的测试函数,使用matplotlib.mplot3d

测试函数主要是用来评估优化算法特性的&#xff0c;这里我用python3绘制了部分测试函数的图像。具体的测试函数可以结合维基百科来了解。想要显示某个测试函数的图片把代码结尾对应的注释去掉即可&#xff0c;具体代码如下&#xff1a; import numpy as np import matplotlib.…

关于C++图论树的某些题图形提示

一、去教室的路。 猫猫大学有n条路&#xff0c;每条路都有一个数字编号&#xff0c;其中的一条路一定与另外2条路相连&#xff0c;请你打出这个学校的地图。 输入1&#xff1a; 1 2 3 4 2 3 45 4 45 1 输出1&#xff1a; 1 2 3 4 5 45 图解 &#xff1…

python实现Edge的爬虫

python实现Edge的爬虫 查看Edge的版本号 下载对应的驱动 官网驱动链接: link 根据自己的系统选择相应的驱动 解压后放在自己的python的Scripts路径&#xff0c;并改名为 MicrosoftWebDriver 安装python库 常用的爬虫库&#xff1a; from bs4 import BeautifulSoup import …

Python爬虫入门系列之Selenium实现动态页面爬取

Python爬虫入门系列之Selenium实现动态页面爬取 在前一篇博客中&#xff0c;我们学习了如何使用多线程优化爬虫程序。但是&#xff0c;如果要爬取的网页是动态生成的或者包含大量JavaScript代码&#xff0c;单纯的静态页面爬取就不足够了。为了解决这个问题&#xff0c;我们可以…

CentOs8开启网卡配置

1.查看网卡文件 ls /etc/sysconfig/network-scripts/ 网卡文件名为 ifcfg-ens160 2.编辑网卡配置 vi /etc/sysconfig/network-scripts/ifcfn-ens160 按Esc结束编辑&#xff0c;然后冒号 : 输入 wq保存并退出 3.启用网卡 nmcli c up ens160 ##centos8网络管理命令 nmcl…

原淘宝npm域名即将停止解析,请切换至新域名

https://developer.aliyun.com/mirror/NPM?spma2c6h.13651102.J_4121707010.2.3e221b11kPiuyz 设置查看npm 国内镜像地址 C:\>npm config get registry http://registry.npmmirror.com/C:\>npm config set registry http://registry.npmmirror.com/C:\>npm config …

【MATLAB第46期】基于MATLAB的改进模糊卷积神经网络IFCNN分类预测模型

【MATLAB第46期】基于MATLAB的改进模糊卷积神经网络IFCNN多分类预测模型 一、展示效果 二、思路 在正常CNN卷积神经网络训练阶段之后&#xff0c;使用进化算法&#xff08;蜜蜂算法&#xff09;拟合深度学习权重和偏差。 本文案例数据中&#xff0c; 用深度模型进行4分类预测…