- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在尝试生成有助于识别热点的 map 叠加图像,即 map 上具有高密度数据点的区域。我尝试过的所有方法都不足以满足我的需求。注意:我忘了提到该算法应该在低缩放场景和高缩放场景(或低和高数据点密度)下都能很好地工作。
我查看了 numpy、pyplot 和 scipy 库,我能找到的最接近的是 numpy.histogram2d。如下图所示, histogram2d 输出相当粗糙。 (每张图片都包含覆盖热图的点以便更好地理解)
我的第二次尝试是遍历所有数据点,然后计算热点值作为距离的函数。这产生了一个更好看的图像,但是在我的应用程序中使用它太慢了。因为它是 O(n),所以它在 100 个点上工作正常,但是当我使用我的 30000 个点的实际数据集时就崩溃了。
我最后的尝试是将数据存储在 KDTree 中,并使用最接近的 5 个点来计算热点值。这个算法是 O(1),对于大型数据集来说要快得多。它仍然不够快,生成 256x256 位图大约需要 20 秒,我希望这在 1 秒左右发生。
编辑
6502 提供的 boxsum 平滑解决方案在所有缩放级别都运行良好,并且比我原来的方法快得多。
Luke 和 Neil G 建议的高斯滤波器解决方案是最快的。
您可以在下面看到所有四种方法,总共使用 1000 个数据点,在 3 倍缩放下大约有 60 个点可见。
生成我最初的 3 次尝试的完整代码、6502 提供的 boxsum 平滑解决方案和 Luke 建议的高斯滤波器(经过改进以更好地处理边缘并允许放大)在这里:
import matplotlib
import numpy as np
from matplotlib.mlab import griddata
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import math
from scipy.spatial import KDTree
import time
import scipy.ndimage as ndi
def grid_density_kdtree(xl, yl, xi, yi, dfactor):
zz = np.empty([len(xi),len(yi)], dtype=np.uint8)
zipped = zip(xl, yl)
kdtree = KDTree(zipped)
for xci in range(0, len(xi)):
xc = xi[xci]
for yci in range(0, len(yi)):
yc = yi[yci]
density = 0.
retvalset = kdtree.query((xc,yc), k=5)
for dist in retvalset[0]:
density = density + math.exp(-dfactor * pow(dist, 2)) / 5
zz[yci][xci] = min(density, 1.0) * 255
return zz
def grid_density(xl, yl, xi, yi):
ximin, ximax = min(xi), max(xi)
yimin, yimax = min(yi), max(yi)
xxi,yyi = np.meshgrid(xi,yi)
#zz = np.empty_like(xxi)
zz = np.empty([len(xi),len(yi)])
for xci in range(0, len(xi)):
xc = xi[xci]
for yci in range(0, len(yi)):
yc = yi[yci]
density = 0.
for i in range(0,len(xl)):
xd = math.fabs(xl[i] - xc)
yd = math.fabs(yl[i] - yc)
if xd < 1 and yd < 1:
dist = math.sqrt(math.pow(xd, 2) + math.pow(yd, 2))
density = density + math.exp(-5.0 * pow(dist, 2))
zz[yci][xci] = density
return zz
def boxsum(img, w, h, r):
st = [0] * (w+1) * (h+1)
for x in xrange(w):
st[x+1] = st[x] + img[x]
for y in xrange(h):
st[(y+1)*(w+1)] = st[y*(w+1)] + img[y*w]
for x in xrange(w):
st[(y+1)*(w+1)+(x+1)] = st[(y+1)*(w+1)+x] + st[y*(w+1)+(x+1)] - st[y*(w+1)+x] + img[y*w+x]
for y in xrange(h):
y0 = max(0, y - r)
y1 = min(h, y + r + 1)
for x in xrange(w):
x0 = max(0, x - r)
x1 = min(w, x + r + 1)
img[y*w+x] = st[y0*(w+1)+x0] + st[y1*(w+1)+x1] - st[y1*(w+1)+x0] - st[y0*(w+1)+x1]
def grid_density_boxsum(x0, y0, x1, y1, w, h, data):
kx = (w - 1) / (x1 - x0)
ky = (h - 1) / (y1 - y0)
r = 15
border = r * 2
imgw = (w + 2 * border)
imgh = (h + 2 * border)
img = [0] * (imgw * imgh)
for x, y in data:
ix = int((x - x0) * kx) + border
iy = int((y - y0) * ky) + border
if 0 <= ix < imgw and 0 <= iy < imgh:
img[iy * imgw + ix] += 1
for p in xrange(4):
boxsum(img, imgw, imgh, r)
a = np.array(img).reshape(imgh,imgw)
b = a[border:(border+h),border:(border+w)]
return b
def grid_density_gaussian_filter(x0, y0, x1, y1, w, h, data):
kx = (w - 1) / (x1 - x0)
ky = (h - 1) / (y1 - y0)
r = 20
border = r
imgw = (w + 2 * border)
imgh = (h + 2 * border)
img = np.zeros((imgh,imgw))
for x, y in data:
ix = int((x - x0) * kx) + border
iy = int((y - y0) * ky) + border
if 0 <= ix < imgw and 0 <= iy < imgh:
img[iy][ix] += 1
return ndi.gaussian_filter(img, (r,r)) ## gaussian convolution
def generate_graph():
n = 1000
# data points range
data_ymin = -2.
data_ymax = 2.
data_xmin = -2.
data_xmax = 2.
# view area range
view_ymin = -.5
view_ymax = .5
view_xmin = -.5
view_xmax = .5
# generate data
xl = np.random.uniform(data_xmin, data_xmax, n)
yl = np.random.uniform(data_ymin, data_ymax, n)
zl = np.random.uniform(0, 1, n)
# get visible data points
xlvis = []
ylvis = []
for i in range(0,len(xl)):
if view_xmin < xl[i] < view_xmax and view_ymin < yl[i] < view_ymax:
xlvis.append(xl[i])
ylvis.append(yl[i])
fig = plt.figure()
# plot histogram
plt1 = fig.add_subplot(221)
plt1.set_axis_off()
t0 = time.clock()
zd, xe, ye = np.histogram2d(yl, xl, bins=10, range=[[view_ymin, view_ymax],[view_xmin, view_xmax]], normed=True)
plt.title('numpy.histogram2d - '+str(time.clock()-t0)+"sec")
plt.imshow(zd, origin='lower', extent=[view_xmin, view_xmax, view_ymin, view_ymax])
plt.scatter(xlvis, ylvis)
# plot density calculated with kdtree
plt2 = fig.add_subplot(222)
plt2.set_axis_off()
xi = np.linspace(view_xmin, view_xmax, 256)
yi = np.linspace(view_ymin, view_ymax, 256)
t0 = time.clock()
zd = grid_density_kdtree(xl, yl, xi, yi, 70)
plt.title('function of 5 nearest using kdtree\n'+str(time.clock()-t0)+"sec")
cmap=cm.jet
A = (cmap(zd/256.0)*255).astype(np.uint8)
#A[:,:,3] = zd
plt.imshow(A , origin='lower', extent=[view_xmin, view_xmax, view_ymin, view_ymax])
plt.scatter(xlvis, ylvis)
# gaussian filter
plt3 = fig.add_subplot(223)
plt3.set_axis_off()
t0 = time.clock()
zd = grid_density_gaussian_filter(view_xmin, view_ymin, view_xmax, view_ymax, 256, 256, zip(xl, yl))
plt.title('ndi.gaussian_filter - '+str(time.clock()-t0)+"sec")
plt.imshow(zd , origin='lower', extent=[view_xmin, view_xmax, view_ymin, view_ymax])
plt.scatter(xlvis, ylvis)
# boxsum smoothing
plt3 = fig.add_subplot(224)
plt3.set_axis_off()
t0 = time.clock()
zd = grid_density_boxsum(view_xmin, view_ymin, view_xmax, view_ymax, 256, 256, zip(xl, yl))
plt.title('boxsum smoothing - '+str(time.clock()-t0)+"sec")
plt.imshow(zd, origin='lower', extent=[view_xmin, view_xmax, view_ymin, view_ymax])
plt.scatter(xlvis, ylvis)
if __name__=='__main__':
generate_graph()
plt.show()
最佳答案
这种方法与之前的一些答案类似:为每个点增加一个像素,然后使用高斯滤波器对图像进行平滑处理。在我使用了 6 年的笔记本电脑上运行 256x256 图像大约需要 350 毫秒。
import numpy as np
import scipy.ndimage as ndi
data = np.random.rand(30000,2) ## create random dataset
inds = (data * 255).astype('uint') ## convert to indices
img = np.zeros((256,256)) ## blank image
for i in xrange(data.shape[0]): ## draw pixels
img[inds[i,0], inds[i,1]] += 1
img = ndi.gaussian_filter(img, (10,10))
关于python - 计算不规则间距点密度的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6652671/
这个问题在这里已经有了答案: Why should there be spaces around '[' and ']' in Bash? (4 个回答) 3年前关闭。 作为初学者,我没有在任何地方找
我有一个程序,我在其中输入 Java 程序来检查输入的字符串是否为回文。我有 2 个问题正在发生,我似乎一辈子都无法解决。 我已经输入了代码,这样它会告诉我它是否是一个回文,当所有小写字母不涉及空格时
table { border: 0; padding: 0; border-collapse: collapse;
我有 10 个单元格,其中第 6 个单元格的宽度必须与其他单元格不同。我试图在流委托(delegate)方法中更改它。但是从第 7 个单元格到第 10 个单元格的间距出了点问题。 func coll
我只是希望将这些新闻发布很好地隔开,以便在每次发布之间留出空隙。我在下面附上了一张图片来解释。我试图增加下面的填充,但这没有用。感谢您的帮助 .headline { position: absolut
如何使用 css 删除表格结构中烦人的单元格间距和/或填充?如果解决方案在 IE7-9、Firefox 和 Chrome 中有效,请加倍支持! 为什么CSS这么难!真让人抓狂! 最佳答案 通常,在该表
我在我正在使用的网站上设置了按钮。我想在按钮外创建一个 2px 的边框,有一点间距。请参见设计图像。 我可以创建边框,但不能创建边框之外的间距。这是当前的开发站点。按钮是第一个图形。 到目前为止我已经
我正在网站上生成元素符号列表(通过使用 jquery 自动完成功能)和我在网站中使用响应式网页设计。 我想在每个列表项后留一个空格。为此,我添加了以下 CSS: li { margin-b
我在格式化我的 HTML 页面时遇到困难。 正如您从源代码中看到的那样,它是一个表格,其中每一行都包含由我的网络应用程序动态填充的格式化记录列表。如果其中一列有空值,我想保留行的格式,所以我基本上应该
我一直致力于设计一个具有三个链接的跨移动设备宽度的设计。我不明白为什么我不能得到正确的间距。什么看起来不对劲? 设计如下: 下面是编码版本的样子: 这是我的 CSS: .b-nav-Wrapper {
我需要在 matplotlib 中生成一大堆垂直堆叠的图。结果将使用 savefig 保存并在网页上查看,所以我不在乎最终图像有多高,只要子图间隔开,这样它们就不会重叠。 无论我允许这个数字有多大,子
我需要在 matplotlib 中生成一大堆垂直堆叠的图。结果将使用 savefig 保存并在网页上查看,所以我不在乎最终图像有多高,只要子图之间有间距,不重叠即可。 无论我允许图有多大,子图似乎总是
是否可以在 BorderPane 上设置节点之间的间距? ? Swing 等效项将是 BorderLayout 上的 hgap 和 vgap . 我在文档中没有找到任何内容,我能想到的唯一可行的解
我有一个基于日历的应用 我希望用户能够通过捏合来放大和缩小日历。这是我的代码: let p = UIPinchGestureRecognizer(target: self, action: #sele
我在为 Android 编写一段代码时遇到问题。我使用的是eclipse开发环境。我想要完成的是将一周中的日子均匀地分布在表格的第一行(有六行)。我不知道如何才能使这些单词真正散开,而不是仅仅粘在一起
我有一个基于日历的应用 我希望用户能够通过捏合来放大和缩小日历。这是我的代码: let p = UIPinchGestureRecognizer(target: self, action: #sele
我该怎么做才能对齐此代码中的所有列?这是正确的还是......? import urllib.request from re import findall def determinarLlegadas
当使用垂直对齐的 BoxLayout 时,如何阻止组件随着包含的 JFrame 的增长而扩展,从而在底部留下额外的空间?我尝试了不同的布局,但很快就变得一团糟。我还尝试在面板底部添加胶水,但布局管理器
我正在尝试制作 cout #include int main() { std::cout << setw(4) << 1 << setw(4) << 2 << std::endl; } 输出
使用示例 http://developer.android.com/guide/tutorials/views/hello-tabwidget.html通过向布局添加 HorizontalScro
我是一名优秀的程序员,十分优秀!