如何使用网格从数据集中采样点?

4

我手头有大约一百万个 (r, phi) 坐标及其强度数据。为了减少内存使用和更快的绘图,我想在一个网格模式下对这些数据进行采样。但是我希望采用 X、Y 坐标进行采样,因为后面我需要将这些坐标转换成 (X,Y) 坐标进行绘图。

我考虑使用 meshgrid 来得到一个采样模板,但我卡在了下一步。

我在 Google 或这里搜索时似乎找不到任何有用的信息,如果这是一个太简单的问题,请谅解!

我正在使用 numpy,并且我的数据目前是存储在三个分离的数组中的。我打算使用 np.meshgrid,然后使用 scipy.interpolate.griddata 进行插值。

rphiintensity 都是形状为 (million,)np.array

例如:

r = array([1560.8, 1560.8003119, 1560.8006238, ..., 3556.831746,
           3558.815873 , 3560.8      ])

我从这个开始;
r = data[:, 0]  # radius
phi = data[:, 1]  # altitude angle
h2o = data[:, 2]  # intensity

x = r * np.sin(phi)  # It's a left handed coordinate system
z = r * np.cos(phi)

至于采样网格,我已经得到了这个:

Xscale = np.linspace(min(x), max(x), 1000)
Zscale = np.linspace(min(z), max(z), 1000)

[X, Z] = np.meshgrid(Xscale, Zscale)

1
你有一个Python标签,你是否使用了像Pandas之类的框架来编写Python程序?可以请你在问题中添加更多细节,并提供你目前所使用的数据结构和/或代码示例吗? - Arch
1个回答

1

如果您提供一些数据进行操作,那就太好了。 无论如何,我们将创建一些数据。

让我们从r,theta任意值创建x,y值:

import numpy as np
import matplotlib.pyplot as plt

theta=np.linspace(0.,50.,1000)
r=np.linspace(5.,10,1000)

x=r*np.sin(theta)
y=r*np.cos(theta)

plt.plot(x,y,linestyle='',marker='.')

这个情节提供:

enter image description here

现在添加任意强度值:

intensity=np.sqrt(x**2+y**2)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, intensity)

散点图提供:

enter image description here

如果我理解正确,我们应该离您的起点不远了。现在我们有3个包含1000个值的数组。我们将把它缩小为一个20x20的网格。 我们首先需要创建x和y的区间,然后调用scipy中的binned_statistic_2d方法,就这样。
import scipy.stats as stats

binx=np.linspace(-10.,10.,20)
biny=np.linspace(-10.,10.,20)

ret = stats.binned_statistic_2d(x, y, intensity, 'mean', bins=[binx,biny])

Z=ret.statistic
Z = np.ma.masked_invalid(Z) # allow to mask Nan values got in bins where there is no value
X, Y = np.meshgrid(binx,biny)

plt.pcolor(X,Y,Z)
plt.show()

pcolor绘图提供了:

enter image description here

根据您的评论请求,我们现在可以回到原始的x、y、z数组结构。
首先,我们必须计算箱子的中心坐标。
binx_centers=(binx[1:] + binx[:-1])/2
biny_centers=(biny[1:] + biny[:-1])/2
Xcenters, Ycenters = np.meshgrid(binx_centers,biny_centers)

然后我们可以获取未屏蔽的值(参见上面的解释)

xnew=np.ma.masked_array(Xcenters, Z.mask).compressed()
ynew=np.ma.masked_array(Ycenters, Z.mask).compressed()
znew=Z.compressed()

我们可以检查新的大小:
print(znew.shape)

只返回了 235 个值(而非 1000 个):

(235L,) 

而新的散点图带有压缩数值:

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(xnew, ynew, znew)

我们获得:

enter image description here


谢谢,这真的很有用!有没有一种方式可以生成更多功能的最终产品?据我所知,这只能使用pcolor绘制。是否有一种方法将其转换为“正常”坐标,即一个3列数组([X Y Z])?如果这很明显,对不起! - Rowan Alethea
我已经修改了答案,包括从网格线开始计算X Y Z数组。 - manu190466

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接