Как выбрать точки из набора данных с помощью сетки? - PullRequest
1 голос
/ 18 июня 2020

Итак, у меня есть данные с примерно миллионом (r, phi) координат вместе с их интенсивностями. Я хочу выбрать эти данные в виде сетки, чтобы уменьшить объем используемой памяти и ускорить построение. Однако я хочу выполнить выборку данных в X, Y, поскольку я буду преобразовывать координаты в координаты (X,Y) для их построения.

Я думал, что могу использовать сетку для создания шаблона, который хотел бы попробовать, но я застрял на следующем шаге.

Кажется, я не могу найти ничего полезного в поиске в Google или здесь, но извиняюсь, если это слишком простой вопрос!

Я использую numpy, и мои данные сейчас хранятся в виде трех отдельных массивов. Я планировал использовать np.meshgrid и более поздние scipy.interpolate.griddata для интерполяции.

r, phi и intensity - все np.array с формой (million,)

например,

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 Ответ

0 голосов
/ 20 июня 2020

Было бы неплохо, если бы вы предоставили некоторые данные для работы. Неважно, мы их создадим.

Давайте создадим значения x, y из r, theta произвольные значения:

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

Now add arbitrary intensity values :

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

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

The scatter plot gives :

enter image description here

If I understand well we should not be far from your starting point. We have now 3 arrays with 1000 values. We are going to reduce it to a 20x20 mesgrid. We have to first create the x and y bins, then call the binned_statistic_2d method from scipy and that's it.

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()

The pcolor plot gives :

enter image description here

As requested in your comment, we can now go back to the original x,y,z arrays structure.

First, we have to calculate the center coordinates of the bins

binx_centers=(binx[1:] + binx[:-1])/2
biny_centers=(biny[1:] + biny[:-1])/2
Xcenters, Ycenters = np.meshgrid(binx_centers,biny_centers)

Then we can get the not masked values (see explanation above)

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

We can check the new size :

print(znew.shape)

Gives only 235 values (instead of 1000.):

(235L,) 

And the new scatter plot with the compressed values :

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

We obtain :

введите описание изображения здесь

...