How to Convert Satellite Data to CSV (Step by Step)
Satellite data arrives as rasters — GeoTIFF images or NetCDF grids — but most analysis happens in spreadsheets, Python dataframes, or BI tools. The bridge between the two is extraction: sampling raster values at your locations and writing them to CSV. Here are the three most practical ways to do it, from no-code to fully automated.
What a good satellite CSV looks like
Before the how, the what. A clean, analysis-ready satellite CSV has:
- One row per location per date (long format — it plays nicely with pivot tables, pandas, and R).
- Stable location IDs plus latitude and longitude columns.
- Clear variable names with units, e.g.
ndvi(unitless, −1 to 1),lst_celsius,precip_mm. - A quality column indicating cloud cover or missing data, so gaps are explainable.
| site_id | lat | lon | date | ndvi | cloud_pct |
|---|---|---|---|---|---|
| field_01 | 48.137 | 11.575 | 2026-06-01 | 0.72 | 3 |
| field_01 | 48.137 | 11.575 | 2026-06-06 | 0.74 | 0 |
| field_02 | 48.201 | 11.442 | 2026-06-01 | 0.58 | 12 |
Method 1: QGIS (no code)
Good for one-off extractions from a handful of files.
- Load your GeoTIFF and your points layer (a CSV with lat/lon imports directly via Layer → Add Delimited Text Layer).
- Check both layers use the same CRS — reproject if not. This is the #1 source of silent errors.
- Run Processing → Toolbox → Sample raster values.
- Export the result: right-click the layer → Export → Save Features As → CSV.
Limitation: this doesn't scale. Fifty dates means fifty rasters and fifty manual runs.
Method 2: Python with rasterio / xarray
The standard automated approach. For a GeoTIFF and a list of points:
import rasterio, open the file with rasterio.open(), and use src.sample(coords) to pull values at your coordinates — then write rows out with pandas' to_csv(). For NetCDF time series (ERA5, CHIRPS), xarray is better: ds.sel(lat=y, lon=x, method="nearest") gives you a full time series per point in one line, and ds.to_dataframe().to_csv() finishes the job.
Things the simple version ignores, and a production pipeline must not:
- Cloud masking — sample the scene classification layer too and drop cloudy observations.
- Projection alignment — transform your WGS84 points into the raster's UTM CRS before sampling.
- Buffering — a single 10 m pixel is noisy; averaging a 3×3 window or a small buffer around each point is usually more robust.
- Nodata values — sentinel values like −9999 must become empty cells, not data.
Method 3: Google Earth Engine (no downloads at all)
Earth Engine hosts the full Sentinel, Landsat, and MODIS archives in the cloud. You upload your points, map a reducer over an image collection, and export straight to CSV — no gigabytes ever touch your disk. The core pattern is ImageCollection.map() with reduceRegions(), then Export.table.toDrive(). For long time series over many points, this is by far the fastest route, and it's free for non-commercial use.
Which method should you pick?
| Situation | Best method |
|---|---|
| One raster, a few points, no coding | QGIS |
| Local files, repeatable pipeline | Python (rasterio/xarray) |
| Long time series, many locations | Google Earth Engine |
| No time to build any of this | Have it done for you ↓ |
Want the CSV without the pipeline? We convert satellite data to analysis-ready CSVs every day — cloud-masked, quality-flagged, and documented. Request your data →