swadhinbiswas style: apply ruff formatting · 8/1/2026
706e694
182 lines · 6.2 KB
Raw Download

« Back to Index

Weather

Weather and Aviation

Weather is the #1 cause of flight delays globally, responsible for ~30–40% of all delay minutes (FAA data). Understanding weather patterns is critical for delay analysis.

Weather Variables Tracked

Variable Unit Range Impact on Aviation
Temperature °C -80 to 60 Extreme heat reduces lift; extreme cold needs de-icing
Humidity % 0 to 100 Fog formation; engine performance
Wind Speed km/h 0 to 300 Crosswind limits; headwind/tailwind affects fuel
Visibility km 0 to 100 Instrument approaches required when < 1.6 km
Precipitation mm/h — Thunderstorms, snow, ice
Pressure hPa — Takeoff/landing performance
Weather Condition category — Clear, Rain, Snow, Fog, Thunderstorm

Weather Condition Categories

Category ICAO Code Aviation Impact
Clear/Sunny CAVOK Normal operations
Rain RA Reduced visibility, wet runway
Heavy Rain +RA Possible ground stops
Snow SN Runway closures, de-icing delays
Blizzard BLSN Airport closure
Fog FG Low visibility, CAT III approaches
Thunderstorm TS Lightning (ramp closures), turbulence
Wind shear WS Go-arounds, diversions
Volcanic ash VA Complete airspace closure

Weather Impact Scaling

Weather Severity Typical Delay Impact
Light rain +5–15 min
Heavy rain / moderate snow +30–60 min
Thunderstorm at hub +2–4 hours (ground stop)
Fog at hub +1–3 hours (reduced arrival rate)
Winter storm Airport closure (hours–days)

Weather Data Model (dim_weather)

Field Type Description
weather_key INTEGER (SK) Surrogate key
station_code VARCHAR(4) Weather station ICAO code
airport_code VARCHAR(3) Associated airport
observation_time TIMESTAMP UTC timestamp
temperature_c DECIMAL(5,1) Temperature in Celsius
dew_point_c DECIMAL(5,1) Dew point
humidity_pct DECIMAL(5,1) Relative humidity %
wind_speed_kmh DECIMAL(5,1) Wind speed
wind_direction INTEGER Wind direction in degrees
visibility_km DECIMAL(5,1) Visibility
pressure_hpa DECIMAL(6,1) Atmospheric pressure
precipitation_mm DECIMAL(5,1) Precipitation
condition VARCHAR(30) Weather condition category
is_adverse BOOLEAN Computed: conditions likely to cause delays

Adversity Classification Logic

def classify_adverse_weather(row):
    """Return True if weather is likely to cause delays."""
    return (
        row["visibility_km"] < 3.0
        or row["wind_speed_kmh"] > 50
        or row["precipitation_mm"] > 5
        or row["condition"] in ["Thunderstorm", "Snow", "Fog", "Blizzard"]
    )

This is_adverse flag is a derived column in Silver/Gold layers that makes weather-delay correlation queries simple:

SELECT
    is_adverse,
    AVG(delay_minutes) AS avg_delay,
    COUNT(*) AS flight_count
FROM fact_flights
JOIN dim_weather ON fact_flights.weather_key = dim_weather.weather_key
GROUP BY is_adverse;

Weather Data Sources

Source Data Access
NOAA/NWS US airports Free API
OpenWeatherMap Global stations Free tier (60 calls/min)
WeatherAPI.com Global Free tier (1M calls/month)
Visual Crossing Historical Free tier (1,000 records/day)
Open-Meteo Global, open-source Free API, no key required ⭐

Recommended for this project: Open-Meteo — free, no API key, global coverage.

# Open-Meteo API example (no API key required)
import requests

url = "https://api.open-meteo.com/v1/forecast"
params = {
    "latitude": 40.6413,  # JFK
    "longitude": -73.7781,
    "hourly": ["temperature_2m", "relative_humidity_2m", "wind_speed_10m", "visibility"],
    "timezone": "UTC",
}
response = requests.get(url, params=params)
weather_data = response.json()

Temporal Joining Strategy

Weather data is typically hourly. Flights have specific departure/arrival timestamps. Strategy:

  1. Store weather at hourly granularity in Silver
  2. When building fact_flights, join the nearest hourly weather observation within ±1 hour of scheduled departure
# Polars temporal join: nearest weather for each flight
flights_with_weather = flights.sort("scheduled_departure").join_asof(
    weather.sort("observation_time"),
    left_on="scheduled_departure",
    right_on="observation_time",
    tolerance="1h",  # within 1 hour
    strategy="nearest",
)

Seasonal Weather Patterns

Season Primary Weather Delays
Summer (Jun–Aug) Thunderstorms at hubs (ATL, ORD, DFW)
Winter (Dec–Feb) Snow/Ice (ORD, DEN, EWR, BOS), Fog (LHR, SFO)
Spring (Mar–May) Wind, turbulence
Fall (Sep–Nov) Hurricane season (Sept–Nov, Gulf Coast)

These patterns feed into seasonal trend Gold tables.

Weather Delay Quantification

-- DuckDB: Measure delay impact per weather condition
SELECT
    w.condition,
    COUNT(*) AS flights,
    ROUND(AVG(f.delay_minutes), 1) AS avg_delay,
    ROUND(PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY f.delay_minutes), 1) AS p95_delay,
    ROUND(SUM(CASE WHEN f.status = 'C' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) AS cancellation_rate
FROM fact_flights f
JOIN dim_weather w ON f.weather_key = w.weather_key
GROUP BY w.condition
ORDER BY avg_delay DESC;

Data Quality Notes for Weather

  • Missing observations: forward-fill from nearest station
  • Extreme values: validate -80 <= temperature <= 60
  • Station ↔ Airport mapping: manual lookup table
  • Time zones: all weather timestamps must be UTC
# Weather validation rules
def validate_weather_row(row) -> bool:
    return (
        -80 <= row["temperature_c"] <= 60
        and 0 <= row["humidity_pct"] <= 100
        and 0 <= row["wind_speed_kmh"] <= 300
        and 0 <= row["visibility_km"] <= 100
        and 800 <= row["pressure_hpa"] <= 1100
    )

« Back to Index