我有一个极性(r,theta)网格(这意味着每个单元格是一个环形区域)包含一些物理量(例如温度)的值,我想重新网格化(或重新投影或重新采样)这些值到笛卡尔网格上.有没有可以做到这一点的Python包?
我对将细胞中心的坐标从极地转换为笛卡尔并不感兴趣 - 这很容易.相反,我正在寻找一个可以实际重新网格化数据的包.
谢谢你的任何建议!
感谢您的回答 - 在仔细考虑了这一点之后,我想出了以下代码:
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as mpl
from scipy.interpolate import interp1d
from scipy.ndimage import map_coordinates
def polar2cartesian(r, t, grid, x, y, order=3):
    X, Y = np.meshgrid(x, y)
    new_r = np.sqrt(X*X+Y*Y)
    new_t = np.arctan2(X, Y)
    ir = interp1d(r, np.arange(len(r)), bounds_error=False)
    it = interp1d(t, np.arange(len(t)))
    new_ir = ir(new_r.ravel())
    new_it = it(new_t.ravel())
    new_ir[new_r.ravel() > r.max()] = len(r)-1
    new_ir[new_r.ravel() < r.min()] = 0
    return map_coordinates(grid, np.array([new_ir, new_it]),
                            order=order).reshape(new_r.shape)
# Define original polar grid
nr = 10
nt = 10
r = np.linspace(1, 100, nr)
t = np.linspace(0., np.pi, nt)
z = np.random.random((nr, nt))
# Define new cartesian grid
nx = 100
ny = 200
x = np.linspace(0., 100., nx)
y = np.linspace(-100., 100., ny)
# Interpolate polar grid to cartesian grid (nearest neighbor)
fig = mpl.figure()
ax = fig.add_subplot(111)
ax.imshow(polar2cartesian(r, t, z, x, y, order=0), interpolation='nearest')
fig.savefig('test1.png')
# Interpolate polar grid to cartesian grid (cubic spline)
fig = mpl.figure()
ax = fig.add_subplot(111)
ax.imshow(polar2cartesian(r, t, z, x, y, order=3), interpolation='nearest')
fig.savefig('test2.png')
这不是严格的重新网格化,但可以满足我的需求.只需发布代码,以防其他人有用.随意提出改进建议!
前段时间我在尝试做类似的事情时来到了这篇文章,即将极地数据重新投影到笛卡尔网格中,反之亦然。这里提出的解决方案工作正常。但是,执行坐标变换需要一些时间。我只是想分享另一种可以将处理时间减少多达 50 倍或更多的方法。
该算法使用该scipy.ndimage.interpolation.map_coordinates函数。
让我们看一个小例子:
import numpy as np
# Auxiliary function to map polar data to a cartesian plane
def polar_to_cart(polar_data, theta_step, range_step, x, y, order=3):
    from scipy.ndimage.interpolation import map_coordinates as mp
    # "x" and "y" are numpy arrays with the desired cartesian coordinates
    # we make a meshgrid with them
    X, Y = np.meshgrid(x, y)
    # Now that we have the X and Y coordinates of each point in the output plane
    # we can calculate their corresponding theta and range
    Tc = np.degrees(np.arctan2(Y, X)).ravel()
    Rc = (np.sqrt(X**2 + Y**2)).ravel()
    # Negative angles are corrected
    Tc[Tc < 0] = 360 + Tc[Tc < 0]
    # Using the known theta and range steps, the coordinates are mapped to
    # those of the data grid
    Tc = Tc / theta_step
    Rc = Rc / range_step
    # An array of polar coordinates is created stacking the previous arrays
    coords = np.vstack((Ac, Sc))
    # To avoid holes in the 360º - 0º boundary, the last column of the data
    # copied in the begining
    polar_data = np.vstack((polar_data, polar_data[-1,:]))
    # The data is mapped to the new coordinates
    # Values outside range are substituted with nans
    cart_data = mp(polar_data, coords, order=order, mode='constant', cval=np.nan)
    # The data is reshaped and returned
    return(cart_data.reshape(len(y), len(x)).T)
polar_data = ... # Here a 2D array of data is assumed, with shape thetas x ranges
# We create the x and y axes of the output cartesian data
x = y = np.arange(-100000, 100000, 1000)
# We call the mapping function assuming 1 degree of theta step and 500 meters of
# range step. The default order of 3 is used.
cart_data = polar_to_cart(polar_data, 1, 500, x, y)
我希望这可以帮助与我处于相同情况的人。
| 归档时间: | 
 | 
| 查看次数: | 11577 次 | 
| 最近记录: |