Python rehearsal
DS Data manipulation, analysis and visualisation in Python
December, 2019© 2016, Joris Van den Bossche and Stijn Van Hoey (mailto:jorisvandenbossche@gmail.com, mailto:stijnvanhoey@gmail.com). Licensed under CC BY 4.0 Creative Commons
In [17]:
pressure_hPa = 1010 # hPa
I'm measuring at sea level, what would be the air pressure of this measured value on other altitudes?
The barometric formula, sometimes called the exponential atmosphere or isothermal atmosphere, is a formula used to model how the pressure (or density) of the air changes with altitude. The pressure drops approximately by 11.3 Pa per meter in first 1000 meters above sea level.
$$P=P_0 \cdot \exp \left[\frac{-g \cdot M \cdot h}{R \cdot T}\right]$$see https://www.math24.net/barometric-formula/ or https://en.wikipedia.org/wiki/Atmospheric_pressure
where:
and:
Let's implement this...
To calculate the formula, I need the exponential operator. Pure Python provide a number of mathematical functions, e.g. https://docs.python.org/3.7/library/math.html#math.exp within the math library
In [18]:
import math
In [19]:
# ...modules and libraries...
from os import *. Just don't!
In [20]:
standard_temperature = 288.15
gas_constant = 8.31446
gravit_acc = 9.81
molar_mass_earth = 0.02896
pressure_hPa (1010 hPa)
In [21]:
height = 2500
pressure_hPa * math.exp(-gravit_acc * molar_mass_earth* height/(gas_constant*standard_temperature))
Out[21]:
In [22]:
# ...function/definition for barometric_formula...
In [23]:
def barometric_formula(pressure_sea_level, height=2500):
"""Apply barometric formula
Apply the barometric formula to calculate the air pressure on a given height
Parameters
----------
pressure_sea_level : float
pressure, measured as sea level
height : float
height above sea level (m)
Notes
------
see https://www.math24.net/barometric-formula/ or
https://en.wikipedia.org/wiki/Atmospheric_pressure
"""
standard_temperature = 288.15
gas_constant = 8.3144598
gravit_acc = 9.81
molar_mass_earth = 0.02896
pressure_altitude = pressure_sea_level * math.exp(-gravit_acc * molar_mass_earth* height/(gas_constant*standard_temperature))
return pressure_altitude
In [24]:
barometric_formula(pressure_hPa, 2000)
Out[24]:
In [25]:
barometric_formula(pressure_hPa)
Out[25]:
In [26]:
# ...formula not valid above 11000m...
# barometric_formula(pressure_hPa, 12000)
In [27]:
def barometric_formula(pressure_sea_level, height=2500):
"""Apply barometric formula
Apply the barometric formula to calculate the air pressure on a given height
Parameters
----------
pressure_sea_level : float
pressure, measured as sea level
height : float
height above sea level (m)
Notes
------
see https://www.math24.net/barometric-formula/ or
https://en.wikipedia.org/wiki/Atmospheric_pressure
"""
if height > 11000:
raise Exception("Barometric formula only valid for heights lower than 11000m above sea level")
standard_temperature = 288.15
gas_constant = 8.3144598
gravit_acc = 9.81
molar_mass_earth = 0.02896
pressure_altitude = pressure_sea_level * math.exp(-gravit_acc * molar_mass_earth* height/(gas_constant*standard_temperature))
return pressure_altitude
In [28]:
# ...combining logical statements...
In [29]:
height > 11000 or pressure_hPa < 9000
Out[29]:
In [30]:
# ...load function from file...
Instead of having the functions in a notebook, importing the function from a file can be done as importing a function from an installed package. Save the function barometric_formula in a file called barometric_formula.py and add the required import statement import math on top of the file. Next, run the following cell:
In [3]:
from barometric_formula import barometric_formula
We can store these in a Python list:
In [31]:
pressures_hPa = [1013, 1003, 1010, 1020, 1032, 993, 989, 1018, 889, 1001]
In [32]:
# ...check methods of lists... append vs insert
In [34]:
# ...list is a container...
I want to calculate the barometric formula for each of these measured values.
In [35]:
# ...for loop... dummy example
for loop that prints the adjusted value for altitude 3000m for each of the pressures in pressures_hPa
In [36]:
for pressure in pressures_hPa:
print(barometric_formula(pressure, 3000))
In [37]:
# ...list comprehensions...
for loop as a list comprehension to calculate the adjusted value for altitude 3000m for each of the pressures in pressures_hPa and store these values in a new variable pressures_hPa_adjusted
In [38]:
pressures_hPa_adjusted = [barometric_formula(pressure, 3000) for pressure in pressures_hPa]
pressures_hPa_adjusted
Out[38]:
In [39]:
import numpy as np
In [40]:
pressures_hPa = [1013, 1003, 1010, 1020, 1032, 993, 989, 1018, 889, 1001]
In [41]:
np_pressures_hPa = np.array([1013, 1003, 1010, 1020, 1032, 993, 989, 1018, 889, 1001])
In [42]:
# ...slicing/subselecting is similar...
In [43]:
print(np_pressures_hPa[0], pressures_hPa[0])
In [ ]:
[] for accessing elements
[start:end:step]
In [48]:
# ...original function using numpy array instead of list... do both
In [49]:
np_pressures_hPa * math.exp(-gravit_acc * molar_mass_earth* height/(gas_constant*standard_temperature))
Out[49]:
It is also a matter of calculation speed:
In [50]:
lots_of_pressures = np.random.uniform(990, 1040, 1000)
In [51]:
%timeit [barometric_formula(pressure, 3000) for pressure in list(lots_of_pressures)]
In [52]:
%timeit lots_of_pressures * np.exp(-gravit_acc * molar_mass_earth* height/(gas_constant*standard_temperature))
In [53]:
np_pressures_hPa
Out[53]:
In [54]:
np_pressures_hPa > 1000
Out[54]:
You can use this as a filter to select elements of an array:
In [55]:
boolean_mask = np_pressures_hPa > 1000
np_pressures_hPa[boolean_mask]
Out[55]:
or, also to change the values in the array corresponding to these conditions:
In [56]:
boolean_mask = np_pressures_hPa < 900
np_pressures_hPa[boolean_mask] = 900
np_pressures_hPa
Out[56]:
Intermezzo: Exercises boolean indexing:
In [57]:
AR = np.random.randint(0, 20, 15)
AR
Out[57]:
In [58]:
sum(AR > 10)
Out[58]:
In [59]:
AR[AR%2 == 0] = 0
AR
Out[59]:
In [60]:
AR[1::2] = 30
AR
Out[60]:
In [61]:
AR2 = np.random.random(10)
AR2
Out[61]:
In [62]:
np.sqrt(AR2[AR2 > np.percentile(AR2, 75)])
Out[62]:
In [63]:
AR3 = np.array([-99., 2., 3., 6., 8, -99., 7., 5., 6., -99.])
In [64]:
AR3[np.isclose(AR3, -99)] = np.nan
AR3
Out[64]:
In [65]:
location = 'Ghent - Sterre'
In [66]:
# ...check methods of strings... split, upper,...
In [ ]:
In [67]:
locations = ['Ghent - Sterre', 'Ghent - Coupure', 'Ghent - Blandijn',
'Ghent - Korenlei', 'Ghent - Kouter', 'Ghent - Coupure',
'Antwerp - Groenplaats', 'Brussels- Grand place',
'Antwerp - Justitipaleis', 'Brussels - Tour & taxis']
In [68]:
[location.lower() for location in locations]
Out[68]:
In [69]:
pressures_hPa = [1013, 1003, 1010, 1020, 1032, 993, 989, 1018, 889, 1001]
temperature_degree = [23, 20, 17, 8, 12, 5, 16, 22, -2, 16]
locations = ['Ghent - Sterre', 'Ghent - Coupure', 'Ghent - Blandijn',
'Ghent - Korenlei', 'Ghent - Kouter', 'Ghent - Coupure',
'Antwerp - Groenplaats', 'Brussels- Grand place',
'Antwerp - Justitipaleis', 'Brussels - Tour & taxis']
Python dictionaries are a convenient way to store multiple types of data together, to not have too much different variables:
In [70]:
measurement = {}
measurement['pressure_hPa'] = 1010
measurement['temperature'] = 23
In [71]:
measurement
Out[71]:
In [72]:
# ...select on name, iterate over keys or items...
In [ ]:
In [73]:
measurements = {'pressure_hPa': pressures_hPa,
'temperature_degree': temperature_degree,
'location': locations}
In [74]:
measurements
Out[74]:
But: I want to apply my barometric function to measurements taken in Ghent when the temperature was below 10 degrees...
In [75]:
for idx, pressure in enumerate(measurements['pressure_hPa']):
if measurements['location'][idx].startswith("Ghent") and \
measurements['temperature_degree'][idx]< 10:
print(barometric_formula(pressure, 3000))
In [76]:
import pandas as pd
In [77]:
measurements = pd.DataFrame(measurements)
measurements
Out[77]:
In [78]:
barometric_formula(measurements[(measurements["location"].str.contains("Ghent")) &
(measurements["temperature_degree"] < 10)]["pressure_hPa"], 3000)
Out[78]: