Assignment #06#
numpy and matplotlib are two fundamental pillars of the scientific python stack. You will find numerous tutorials for both libraries online. I am asking you to learn the basics of both tools by yourself, at the pace that suits you. I can recommend these two tutorials:
They can be quite long if you are new to numpy - I am not asking you to do them all today! Sections 1.4.1.1 to 1.4.1.5 in the numpy tutorial should get you enough information for today’s assignments, or you can try without it and learn on the fly - your choice!
Exercise #06-01: Indexing#
Given a 2D numpy array defined as:
import numpy as np
x = np.array([[1, 2, 3],
[4, 5, 6]])
The following indexing operations all select the same values out of the array:
x[:, 1]
x[slice(0, 2, 1), 1]
x[(slice(0, 2, 1), 1)]
x[slice(0, 2, 1), slice(1, 2, 1)]
x[..., 1]
x[::1, 1]
x[[0, 1], 1]
x[:, -2]
x[:, 1:2]
x[:, [1]]
This can be checked with the following test:
from numpy.testing import assert_equal
ref = 7
assert_equal(ref, x[:, 1].sum())
assert_equal(ref, x[..., 1].sum())
assert_equal(ref, x[::1, 1].sum())
assert_equal(ref, x[slice(0, 2, 1), 1].sum())
assert_equal(ref, x[(slice(0, 2, 1), 1)].sum())
assert_equal(ref, x[slice(0, 2, 1), slice(1, 2, 1)].sum())
assert_equal(ref, x[[0, 1], 1].sum())
assert_equal(ref, x[:, -2].sum())
assert_equal(ref, x[:, 1:2].sum())
assert_equal(ref, x[:, [1]].sum())
Questions:
What is the
...
syntax doing? Again, it is the literal equivalent of an actual python object: which one?Some of these indexing operations are truly equivalent to the “obvious” one,
x[:, 1]
. List them.Classify these operations (i) into basic and advanced operations, and (ii) by the shape of their output. Explain.
If you would like the array
a = x[:, 1:2]
to have a shape of (2, ) like most of the other operations listed above, how can you reshape it?
Hint: Take a look at the numpy documentation about indexing.
Exercise #06-02: Average temperature#
Monthly averages of temperature data at Innsbruck can be downloaded from this lecture’s github repository via:
from urllib.request import Request, urlopen
import json
# Parse the given url
url = 'https://raw.githubusercontent.com/manuelalehner/scientific_programming/master/data/innsbruck_temp.json'
req = urlopen(Request(url)).read()
# Read the data
inn_data = json.loads(req.decode('utf-8'))
(original data obtained from NOAA’s Global Surface Summary of the Day)
Explore the inn_data variable. What is the type of “inn_data”, and of the data it contains?
Convert the data series to numpy arrays.
Using numpy/scipy, matplotlib, and the standard library only, compute and plot the mean monthly annual cycle of temperature for 1981-2010 and the mean annual temperature timeseries for 1977-2017.
Compute the linear trend (using scipy.stats.linregress) of the average annual temperature over the period 1977-2017.
Repeat for the winter (DJF) and summer (JJA) trends.
Tip 1: to select part of an array (indexing) based on a condition, you can use the following syntax:
import numpy as np
x = np.arange(10)
y = x**2
y[x > 4] # select y based on the values in x
array([25, 36, 49, 64, 81])
Tip 2: there is more than one way to compute the annual and monthly means. Some use loops, some use reshaping of the original 1D array.
Exercise #06-03: Plotting gridded temperature#
ERA-Interim reanalysis provides global atmospheric fields from 1979 to 2019. You can access a prepared dataset of gridded average temperature here:
from urllib.request import Request, urlopen
from io import BytesIO
import json
# Parse the given url
url = 'https://raw.githubusercontent.com/manuelalehner/scientific_programming/master/data/monthly_temp.npz'
req = urlopen(Request(url)).read()
with np.load(BytesIO(req)) as data:
temp = data['temp']
lon = data['lon']
lat = data['lat']
However, the dataset is not well processed! The longitudes are ranging from 0 to 360°, thus cutting UK and Africa in half! Reorganize the data and the corresponding coordinates to obtain a plot similar to this one: