Skip to content

Tips and Tricks #1 – changing the dimensions of arrays

  • blog
round life buoy

I’m starting a new series of irregular short posts on some tips and tricks on using Geospatial Python. They may not be best practice, but I hope they are of help. I’ll try and give some context to when I’ve used the ‘tip’.

First up, interoperability. Specifically in Rasterio

This is already very well documented here in much greater detail

When you read an image into rasterio the shape is commonly in the format

(3, 519, 751)

or

(bands, rows, columns)


but often we want

(rows, columns, band)

I’ve often solved this but manipulating the array in numpy, but as we can actually do this within rasterio using

reshape_as_image or reshape_as_raster

For example:

import rasterio
from rasterio.plot import reshape_as_raster, reshape_as_image
import numpy as np
with rasterio.open(raster_file) as src: 
   data = src.read() # gets ALL the data 

print (f'Normally expect this shape from rasterio: {data.shape}') 
# https://rasterio.readthedocs.io/en/latest/topics/image_processing.html 

image = reshape_as_image(data) 
print(f'After reshaping as image: {image.shape}') 

reshaped_to_raster = reshape_as_raster(image) 
print(f'After reshaping as raster: {reshaped_to_raster.shape}')

This will print out:

Normally expect this shape from rasterio: (3, 519, 751)
After reshaping as image: (519, 751, 3)
After reshaping as raster: (3, 519, 751)

A bonus

Sometimes you read a raster in as a single band eg

(519, 751)

(rows, columns)

but actually you want (some deep learning pipelines like this)

(519, 751, 1)

(rows, columns, band)

Well we can add a dimension using numpy with numpy.expand_dims

for example (reusing the code above):

with rasterio.open(raster_file) as src:
    data = src.read() # gets ALL the data
    single_band = data[0] # gets the first band OR src.read(1)

print(f'first band, or a single band image: {single_band.shape}')

added_dimension = np.expand_dims(single_band, axis=2)

print(f'After adding a dimension: {added_dimension.shape}')
print('---------------')
print(added_dimension[:,:,0])

This will print out

first band, or a single band image: (519, 751)
After adding a dimension: (519, 751, 1)
—————
[[ 687. 676. 680. … 1010. 1006. 977.]
[ 688. 681. 679. … 992. 986. 996.]
[ 688. 686. 680. … 982. 1002. 977.]

[ 891. 882. 912. … 1472. 1360. 1443.]
[ 902. 868. 893. … 1455. 1342. 1354.]
[ 943. 931. 966. … 1362. 1249. 1009.]]

I’ve added comments where needed to the code here. I hope this has been of use.

I’ll be adding more tips and tricks


Image credit https://unsplash.com/photos/MJAoiige14E

I am a freelancer able to help you with your projects. I offer consultancy, training and writing. I’d be delighted to hear from you.

Feel free to connect or follow me; I am always keen to talk about Earth Observation.

I am @map_andrew on twitter