Python/SciPy问题:极坐标DataFrame转笛卡尔网格遇阻
Got it, let's walk through converting your PPI arc scan data from polar (azimuth + radial distance) to Cartesian coordinates, and regrid it into a 2D x/y array. I'll use Python tools you're already working with—pandas, numpy, and scipy—since that's the most straightforward stack for this task.
First, let's make sure we're working with the right inputs. Your DataFrame has 30 rows (each for an azimuth angle) and 197 columns (each for a radial distance). Let's load it and extract the key components:
import pandas as pd import numpy as np from scipy.interpolate import griddata # Load your CSV data (replace with your actual file path) ppi_df = pd.read_csv('your_ppi_scan.csv') # Extract azimuth angles (assuming rows are labeled with azimuth values; adjust if they're a dedicated column!) azimuths = ppi_df.index.values # If azimuths are in a column instead: azimuths = ppi_df['azimuth'].values # Extract radial distances (convert column names to floats, since they're likely numeric values) radial_distances = ppi_df.columns.values.astype(float) # Grab the raw measurement values (e.g., radial wind speed) from the DataFrame ppi_values = ppi_df.values
Meteorological PPI scans usually use 0° as north, but mathematical polar coordinates treat 0° as east. We'll adjust for that mismatch first, then calculate x/y coordinates for every point in your PPI grid:
# Convert azimuths from degrees to radians, and reorient to match mathematical polar coordinates theta = np.radians(90 - azimuths) # Shifts north (0°) to the 90° position, aligning east with 0° # Create a meshgrid pairing every radial distance with every azimuth angle r_mesh, theta_mesh = np.meshgrid(radial_distances, theta) # Calculate Cartesian x and y for each point in the mesh x = r_mesh * np.cos(theta_mesh) y = r_mesh * np.sin(theta_mesh)
Now we need to set up the x/y grid you want to regrid into. You can adjust the resolution to match your analysis needs (e.g., 10m, 50m cells):
# Set your desired grid cell size (adjust this to fit your use case) grid_resolution = 10 # Units: meters # Define the full bounds of the grid based on your original data's extent x_min, x_max = x.min(), x.max() y_min, y_max = y.min(), y.max() # Generate the grid points x_grid = np.arange(x_min, x_max + grid_resolution, grid_resolution) y_grid = np.arange(y_min, y_max + grid_resolution, grid_resolution) X_grid, Y_grid = np.meshgrid(x_grid, y_grid)
We'll use nearest-neighbor interpolation as you requested, with the option to fill out-of-bounds points with NaN or 0:
# Perform nearest-neighbor interpolation onto the target grid cartesian_grid = griddata( points=(x.flatten(), y.flatten()), # All original (x,y) points from the PPI scan values=ppi_values.flatten(), # All corresponding measurement values xi=(X_grid, Y_grid), # The target Cartesian grid points method='nearest', fill_value=np.nan # Swap this to 0 if you prefer zero-padding instead of missing values )
- If your azimuths use a different reference (e.g., 0° east), skip the
90 - azimuthsadjustment in the theta calculation. - If your radial distance column names include non-numeric characters (like "m" for meters), clean them first before converting to float.
- Adjust
grid_resolutionto make your output grid coarser or finer. - Swap
fill_value=np.nantofill_value=0if zero-padding makes more sense for your analysis.
That's it! The cartesian_grid variable is your 2D array aligned to the x/y grid you defined, ready for plotting or further analysis.
内容的提问来源于stack exchange,提问作者Elliot

