Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用numpy数组计算规则栅格单元内的点数_Python_Numpy_Scipy - Fatal编程技术网

Python 使用numpy数组计算规则栅格单元内的点数

Python 使用numpy数组计算规则栅格单元内的点数,python,numpy,scipy,Python,Numpy,Scipy,我正在处理大量的3D点,每个点的x、y、z值存储在numpy数组中。 对于背景,点将始终位于固定半径的圆柱体内,高度=点的最大z值。 我的目标是将边界圆柱体(或柱体,如果更容易的话)拆分为例如1m高的地层,然后计算每个单元内的点数 覆盖在每个地层上的规则网格(例如1 m x 1 m) 从概念上讲,该操作与覆盖光栅和计算与每个像素相交的点相同。 网格状的细胞可以形成正方形或圆盘,这无关紧要 经过大量的搜索和阅读,我目前的想法是使用numpy.linspace和numpy.meshgrid的一些组合

我正在处理大量的3D点,每个点的x、y、z值存储在numpy数组中。 对于背景,点将始终位于固定半径的圆柱体内,高度=点的最大z值。 我的目标是将边界圆柱体(或柱体,如果更容易的话)拆分为例如1m高的地层,然后计算每个单元内的点数 覆盖在每个地层上的规则网格(例如1 m x 1 m)

从概念上讲,该操作与覆盖光栅和计算与每个像素相交的点相同。 网格状的细胞可以形成正方形或圆盘,这无关紧要

经过大量的搜索和阅读,我目前的想法是使用numpy.linspace和numpy.meshgrid的一些组合来生成存储在数组中的每个单元的顶点,并针对每个点测试每个单元,看看它是否“在”。这似乎效率低下,尤其是在使用数千个点时

numpy/scipy套件似乎非常适合这个问题,但我还没有找到解决方案。如有任何建议,将不胜感激。 我已经包括了一些示例点和一些可视化数据的代码

# Setup
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Load in X,Y,Z values from a sub-sample of 10 points for testing
# XY Values are scaled to a reasonable point of origin
z_vals = np.array([3.08,4.46,0.27,2.40,0.48,0.21,0.31,3.28,4.09,1.75])
x_vals = np.array([22.88,20.00,20.36,24.11,40.48,29.08,36.02,29.14,32.20,18.96])
y_vals = np.array([31.31,25.04,31.86,41.81,38.23,31.57,42.65,18.09,35.78,31.78])

# This plot is instructive to visualize the problem
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x_vals, y_vals, z_vals, c='b', marker='o')
plt.show()

我不确定我是否完全理解您在寻找什么,但由于每个“单元”似乎都有一个1m的侧面,所以您不能:

  • 可能使用一些
    floor
    函数将所有值四舍五入为整数(光栅化数据)
  • 从这些整数坐标创建一个双射,使用以下方法更方便:

    (64**2)*x+(64)*y+z#假设所有值都在[0,63]中

    如果以后想更轻松地关注身高,可以将
    z
    放在开头

  • 计算每个“单元”的柱状图(numpy/scipy或numpy中的几个函数可以做到这一点)

  • 如果需要,还原双射(即,一旦知道计数,就知道每个单元格的“真”坐标)

也许我不太明白,但如果有帮助的话…

谢谢@Baruchel。事实证明@DilithiumMatrix建议的n维直方图为我发布的问题提供了一个相当简单的解决方案。经过一番阅读,以下是我目前对其他面临类似问题的人的解决方案。 由于这是我第一次使用Python/Numpy,因此欢迎提出任何改进/建议,特别是关于性能的改进/建议。谢谢

# Setup
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Load in X,Y,Z values from a sub-sample of 10 points for testing
# XY Values are scaled to a reasonable point of origin
z_vals = np.array([3.08,4.46,0.27,2.40,0.48,0.21,0.31,3.28,4.09,1.75])
x_vals = np.array([22.88,20.00,20.36,24.11,40.48,29.08,36.02,29.14,32.20,18.96])
y_vals = np.array([31.31,25.04,31.86,41.81,38.23,31.57,42.65,18.09,35.78,31.78])

# Updated code below
# Variables needed for 2D,3D histograms
xmax, ymax, zmax = int(x_vals.max())+1, int(y_vals.max())+1, int(z_vals.max())+1
xmin, ymin, zmin = int(x_vals.min()), int(y_vals.min()), int(z_vals.min())
xrange, yrange, zrange = xmax-xmin, ymax-ymin, zmax-zmin
xedges = np.linspace(xmin, xmax, (xrange + 1), dtype=int)
yedges = np.linspace(ymin, ymax, (yrange + 1), dtype=int)
zedges = np.linspace(zmin, zmax, (zrange + 1), dtype=int)

# Make the 2D histogram
h2d, xedges, yedges = np.histogram2d(x_vals, y_vals, bins=(xedges, yedges))
assert np.count_nonzero(h2d) == len(x_vals), "Unclassified points in the array"
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
plt.imshow(h2d.transpose(), extent=extent,  interpolation='none', origin='low')
# Transpose and origin must be used to make the array line up when using imshow, unsure why
# Plot settings, not sure yet on matplotlib update/override objects
plt.grid(b=True, which='both')
plt.xticks(xedges)
plt.yticks(yedges)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.plot(x_vals, y_vals, 'ro')
plt.show()

# 3-dimensional histogram with 1 x 1 x 1 m bins. Produces point counts in each 1m3 cell.
xyzstack = np.stack([x_vals,y_vals,z_vals], axis=1)
h3d, Hedges = np.histogramdd(xyzstack, bins=(xedges, yedges, zedges))
assert np.count_nonzero(h3d) == len(x_vals), "Unclassified points in the array"
h3d.shape  # Shape of the array should be same as the edge dimensions
testzbin = np.sum(np.logical_and(z_vals >= 1, z_vals < 2))  # Slice to test with
np.sum(h3d[:,:,1]) == testzbin  # Test num points in second bins
np.sum(h3d, axis=2)  # Sum of all vertical points above each x,y 'pixel'
# only in this example the h2d and np.sum(h3d,axis=2) arrays will match as no z bins have >1 points

# Remaining issue - how to get a r x c count of empty z bins.
# i.e. for each 'pixel'  how many z bins contained no points?
# Possible solution is to reshape to use logical operators
count2d = h3d.reshape(xrange * yrange, zrange)  # Maintain dimensions per num 3D cells defined
zerobins = (count2d == 0).sum(1)
zerobins.shape
# Get back to x,y grid with counts - ready for output as image with counts=pixel digital number
bincount_pixels = zerobins.reshape(xrange,yrange)
# Appears to work, perhaps there is a way without reshapeing?
#设置
将numpy作为np导入
将matplotlib.pyplot作为plt导入
从mpl_toolkits.mplot3d导入Axes3D
#从10个测试点的子样本中加载X、Y、Z值
#XY值被缩放到合理的原点
z_vals=np.数组([3.08,4.46,0.27,2.40,0.48,0.21,0.31,3.28,4.09,1.75])
x_vals=np.数组([22.88,20.00,20.36,24.11,40.48,29.08,36.02,29.14,32.20,18.96])
y_vals=np.数组([31.31,25.04,31.86,41.81,38.23,31.57,42.65,18.09,35.78,31.78])
#更新代码如下
#二维、三维直方图所需的变量
xmax,ymax,zmax=int(x_vals.max())+1,int(y_vals.max())+1,int(z_vals.max())+1
xmin,ymin,zmin=int(x_vals.min()),int(y_vals.min()),int(z_vals.min())
xrange,yrange,zrange=xmax xmin,ymax ymin,zmax zmin
xedges=np.linspace(xmin,xmax,(xrange+1),dtype=int)
yedges=np.linspace(ymin,ymax,(yrange+1),dtype=int)
zedges=np.linspace(zmin,zmax,(zrange+1),dtype=int)
#制作二维直方图
h2d,xedges,yedges=np.histogram2d(x值,y值,bins=(xedges,yedges))
断言np.count_nonzero(h2d)=len(x_vals),“数组中的未分类点”
范围=[xedges[0],xedges[-1],yedges[0],yedges[-1]]
plt.imshow(h2d.transpose(),extent=extent,interpolation='none',origin='low')
#使用imshow时,必须使用转置和原点使数组对齐,但不确定原因
#打印设置,尚未确定matplotlib更新/覆盖对象
plt.grid(b=True,其中='tware')
plt.xticks(xedges)
plt.yticks(yedges)
plt.xlabel('X轴')
plt.ylabel(“Y轴”)
plt.绘图(x值、y值、ro值)
plt.show()
#带有1 x 1 x 1 m箱的三维直方图。在每个1m3单元中生成点计数。
xyzstack=np.stack([x_vals,y_vals,z_vals],轴=1)
h3d,Hedges=np.Historogramdd(xyzstack,bin=(xedges,yedges,zedges))
断言np.count_nonzero(h3d)=len(x_vals),“数组中的未分类点”
h3d.shape#阵列的形状应与边缘尺寸相同
testzbin=np.sum(np.logical_和(z_vals>=1,z_vals<2))#用于测试的切片
np.sum(h3d[:,:,1])==testzbin#第二个箱子中的测试点数
np.总和(h3d,轴=2)#每个x,y‘像素’上方所有垂直点的总和
#只有在本例中,h2d和np.sum(h3d,轴=2)数组才会匹配,因为没有z仓具有>1个点
#剩余问题-如何获得空z箱的r x c计数。
#即,对于每个“像素”,有多少个z箱不包含点?
#可能的解决方案是重新构造以使用逻辑运算符
count2d=h3d.重塑(xrange*yrange,zrange)#保持定义的每个3D单元格的尺寸
zerobins=(count2d==0)。总和(1)
零仓形状
#返回带有计数的x,y网格-准备输出为带有计数=像素数字的图像
bincount_pixels=zerobins.重塑(X范围,Y范围)
#看似可行,或许有没有办法不重塑?
PS如果您面临类似问题,scikit补丁提取看起来是另一种可能的解决方案