使用Python计算点密度

时间:2012-12-28 13:53:03

标签: python

我有一个来自世界特定地区的地理数据的X和Y坐标列表。我想根据它在图表中的位置来分配每个坐标,一个权重。

例如:如果一个点位于其周围有许多其他节点的地方,则它位于高密度区域,因此具有更高的权重。

我能想到的最直接的方法是在每个点周围绘制单位半径圆,然后计算其他点是否位于其中,然后使用函数,为该点指定权重。但这似乎是原始的。

我看过pySAL和NetworkX,但看起来它们适用于图形。我在图表中没有任何边缘,只有节点。

4 个答案:

答案 0 :(得分:3)

如果你有很多分数,你可以使用KDTree更有效地计算最近邻居:

import numpy as np
import scipy.spatial as spatial
points = np.array([(1, 2), (3, 4), (4, 5), (100,100)])
tree = spatial.KDTree(np.array(points))
radius = 3.0

neighbors = tree.query_ball_tree(tree, radius)
print(neighbors)
# [[0, 1], [0, 1, 2], [1, 2], [3]]

tree.query_ball_tree返回最近邻居的索引(points)。例如,[0,1](在索引0处)表示points[0]points[1]radius的距离points[0]范围内。 [0,1,2](在索引1处)表示points[0]points[1]points[2]radius的距离points[1]范围内。

frequency = np.array(map(len, neighbors))
print(frequency)
# [2 3 2 1]
density = frequency/radius**2
print(density)
# [ 0.22222222  0.33333333  0.22222222  0.11111111]

答案 1 :(得分:3)

标准解决方案是使用KDE(Kernel Density Estimation) 在网上搜索:" KDE估算"你会发现很多链接。 在谷歌类型:KDE估计分机:pdf
此外,Scipy有KDE,请遵循此http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html。那里有工作示例代码;)

答案 2 :(得分:1)

是的,你确实有边缘,它们是节点之间的距离。在您的情况下,您有一个带加权边的完整图表。

只需导出每个节点到另一个节点的距离 - 这会给你O(N^2)时间复杂度 - 并使用节点和边缘作为你找到的这些方法之一的输入。

虽然你的问题似乎只是一个分析问题而不是其他任何东西;你应该尝试对数据运行一些聚类算法,比如K-means,它根据距离函数聚类节点,你可以在其中简单地使用欧几里德距离。

此算法的结果正是您所需要的,因为您将拥有关闭元素的集群,您将知道为每个组分配了多少元素,并且您将能够根据对这些值,生成要分配给每个节点的系数

值得指出的唯一值得关注的是,您必须确定要创建的clusters - k-means, k-clusters的数量。

答案 3 :(得分:1)

你最初倾向于在每个点周围绘制一个圆并计算该圆中其他点的数量是一个很好的,并且如unutbu所述,KDTree将是解决此问题的快速方法。

这可以通过PySAL轻松完成,它使用了scipy的kdtree。

import pysal
import numpy
pts = numpy.random.random((100,2)) #generate some random points
radius = 0.2 #pick an arbitrary radius

#Build a Spatial Weights Matrix
W = pysal.threshold_continuousW_from_array(pts, threshold=radius)
# Note: if your points are in Latitude and Longitude you can increase the accuracy by
#       passing the radius of earth to this function and it will use arc distances.
# W = pysal.threshold_continuousW_from_array(pts, threshold=radius, radius=pysal.cg.RADIUS_EARTH_KM)

print W.cardinalities
#{0: 10, 1: 15, ..... }

如果您的数据在Shapefile中,只需将threshold_continuousW_from_array替换为threshold_continuousW_from_shapefile,有关详细信息,请参阅文档。