{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Data Structures" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "ename": "ModuleNotFoundError", "evalue": "No module named 'rasterio'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpandas\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mgeopandas\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mrasterio\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mrasterio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mshow\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mrioshow\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'rasterio'" ] } ], "source": [ "%matplotlib inline\n", "\n", "import pandas\n", "import geopandas\n", "import rasterio\n", "from rasterio.plot import show as rioshow" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Contents\n", "\n", "* [Core data types](#Core-data-types)\n", "* [Reading (spatial) data](#Reading-(spatial)-data)\n", "* [`(Geo)DataFrames`](#(Geo)DataFrames)\n", "* [`Series`](#Series)\n", "* [The `geometry` column](#The-geometry-column)\n", " * [CRS](#CRS)\n", " * [Geometries](#Geometries)\n", " * [Geometric operations](#Geometric-operations)\n", "* [A note on rasters](#A-note-on-rasters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Core data types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Core:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(1)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(1.0)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type('a')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type('hello world!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Extensions:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Timestamp('2019-11-05 09:00:00')" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pandas.to_datetime(\"2019-11-05 9:00\")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[Apples, Oranges]\n", "Categories (2, object): [Apples, Oranges]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pandas.Categorical([\"Apples\", \"Oranges\"])" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from shapely.geometry import Point\n", "\n", "Point(-0.08947918950509948, 51.49441830214852)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading (spatial) data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For non-spatial data, we use `pandas` and its `read_XXX` methods. Have a peak at what's available by typing `pandas.read_` and pressing `TAB`; auto-completion will show you all supported file formats." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For spatial data, `geopandas` *extends* `pandas` functionality to support vector spatial data. Let's illustrate its main `read_file` method with a dataset of AirBnb aggregate statistics for Inner London:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "db = geopandas.read_file('../data/lux_regions.gpkg')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `(Geo)DataFrames`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When you read a multi-column tabular file, a `DataFrame` is created. If that table contains spatial information and is read with `geopandas`, you get a `GeoDataFrame`:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "geopandas.geodataframe.GeoDataFrame" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(db)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Both data structures are very similar and modeled after relational databases like SQL (and not completely unlike an Excel Spreadsheet!). Let's print the top (\"head\") of the table to inspect its contents:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
POPULATIONCOMMUNE_1LAU2_subtypeCOMMUNEDISTRICTCANTONtree_countghsl_poplight_levelgeometry
010750Schifflange0214Inspire_10072018SchifflangeLuxembourgEsch-sur-Alzette3.07699.378065681.0POLYGON ((5.999664443592493 49.51861834298563,...
11265Bech1002Inspire_10072018BechGrevenmacherEchternach4.01156.143936567.0POLYGON ((6.347791382484162 49.76015684859829,...
235040Esch-sur-Alzette0204Inspire_10072018Esch-sur-AlzetteLuxembourgEsch-sur-Alzette0.030072.8041721370.0POLYGON ((5.966652609366625 49.51287419342548,...
38169Walferdange0310Inspire_10072018WalferdangeLuxembourgLuxembourg4.07496.442968730.0POLYGON ((6.125796013396808 49.66347171771235,...
49440Mersch0409Inspire_10072018MerschLuxembourgMersch9.08168.8358422388.0POLYGON ((6.08267171189537 49.77458013764257, ...
\n", "
" ], "text/plain": [ " POPULATION COMMUNE_1 LAU2 _subtype COMMUNE \\\n", "0 10750 Schifflange 0214 Inspire_10072018 Schifflange \n", "1 1265 Bech 1002 Inspire_10072018 Bech \n", "2 35040 Esch-sur-Alzette 0204 Inspire_10072018 Esch-sur-Alzette \n", "3 8169 Walferdange 0310 Inspire_10072018 Walferdange \n", "4 9440 Mersch 0409 Inspire_10072018 Mersch \n", "\n", " DISTRICT CANTON tree_count ghsl_pop light_level \\\n", "0 Luxembourg Esch-sur-Alzette 3.0 7699.378065 681.0 \n", "1 Grevenmacher Echternach 4.0 1156.143936 567.0 \n", "2 Luxembourg Esch-sur-Alzette 0.0 30072.804172 1370.0 \n", "3 Luxembourg Luxembourg 4.0 7496.442968 730.0 \n", "4 Luxembourg Mersch 9.0 8168.835842 2388.0 \n", "\n", " geometry \n", "0 POLYGON ((5.999664443592493 49.51861834298563,... \n", "1 POLYGON ((6.347791382484162 49.76015684859829,... \n", "2 POLYGON ((5.966652609366625 49.51287419342548,... \n", "3 POLYGON ((6.125796013396808 49.66347171771235,... \n", "4 POLYGON ((6.08267171189537 49.77458013764257, ... " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other quick exploratory methods:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 102 entries, 0 to 101\n", "Data columns (total 11 columns):\n", "POPULATION 102 non-null int64\n", "COMMUNE_1 102 non-null object\n", "LAU2 102 non-null object\n", "_subtype 102 non-null object\n", "COMMUNE 102 non-null object\n", "DISTRICT 102 non-null object\n", "CANTON 102 non-null object\n", "tree_count 102 non-null float64\n", "ghsl_pop 102 non-null float64\n", "light_level 102 non-null float64\n", "geometry 102 non-null object\n", "dtypes: float64(3), int64(1), object(7)\n", "memory usage: 8.9+ KB\n" ] } ], "source": [ "db.info()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(102, 11)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db.shape" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
POPULATIONtree_countghsl_poplight_level
count102.000000102.000000102.000000102.000000
mean5902.0098045.2450985542.1616661076.931373
std12231.2439235.62778911155.324437749.838811
min790.0000000.000000815.144388299.000000
25%1915.0000002.0000001726.167268628.750000
50%2937.5000004.0000003072.414461896.500000
75%5489.0000007.0000005190.1778611255.250000
max116323.00000043.000000106143.9568255614.000000
\n", "
" ], "text/plain": [ " POPULATION tree_count ghsl_pop light_level\n", "count 102.000000 102.000000 102.000000 102.000000\n", "mean 5902.009804 5.245098 5542.161666 1076.931373\n", "std 12231.243923 5.627789 11155.324437 749.838811\n", "min 790.000000 0.000000 815.144388 299.000000\n", "25% 1915.000000 2.000000 1726.167268 628.750000\n", "50% 2937.500000 4.000000 3072.414461 896.500000\n", "75% 5489.000000 7.000000 5190.177861 1255.250000\n", "max 116323.000000 43.000000 106143.956825 5614.000000" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db.describe()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `Series`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`DataFrames` are two-dimensional array-like structures (think a matrix but with mixed types), and are \"made up\" of `Series`, which are one-dimensional objects (think of vectors). " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 10750\n", "1 1265\n", "2 35040\n", "3 8169\n", "4 9440\n", "Name: POPULATION, dtype: int64" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db['POPULATION'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The `geometry` column" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 POLYGON ((5.999664443592493 49.51861834298563,...\n", "1 POLYGON ((6.347791382484162 49.76015684859829,...\n", "2 POLYGON ((5.966652609366625 49.51287419342548,...\n", "3 POLYGON ((6.125796013396808 49.66347171771235,...\n", "4 POLYGON ((6.08267171189537 49.77458013764257, ...\n", "Name: geometry, dtype: object" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db['geometry'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remember:\n", "\n", "- (Almost) like a standard `Series` object\n", "- Only one per `GeoDataFrame`\n", "- Extends `pandas` bringing all sorts of geospatial goodies" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### CRS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Small but powerful attribute:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'init': 'epsg:4326'}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db.crs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**IMPORTANT**: `crs` is an attribute of a `GeoDataFrame`, not of each geometry!" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "db_wgs84 = db.to_crs(epsg=4326)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Geometries" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "poly = db.loc[0, 'geometry']" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "poly" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(5.993289939672974, 49.483288039852084, 6.041161215183009, 49.52370478379051)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "poly.bounds" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.0009631318046161011" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "poly.area" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "#poly.crs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Geometric operations" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "poly2 = db.loc[27, 'geometry']\n", "poly2" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "poly.touches(poly2)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "poly.intersects(poly2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we can \"broadcast\" this too!" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 False\n", "1 False\n", "2 True\n", "3 False\n", "4 False\n", " ... \n", "97 False\n", "98 False\n", "99 False\n", "100 False\n", "101 False\n", "Length: 102, dtype: bool" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db.touches(poly)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
POPULATIONCOMMUNE_1LAU2_subtypeCOMMUNEDISTRICTCANTONtree_countghsl_poplight_levelgeometry
235040Esch-sur-Alzette0204Inspire_10072018Esch-sur-AlzetteLuxembourgEsch-sur-Alzette0.030072.8041721370.0POLYGON ((5.966652609366625 49.51287419342548,...
711003Bettembourg0201Inspire_10072018BettembourgLuxembourgEsch-sur-Alzette1.011060.8217531909.0POLYGON ((6.06035425169626 49.54561673366194, ...
419098Kayl0206Inspire_10072018KaylLuxembourgEsch-sur-Alzette7.06947.8241431267.0POLYGON ((6.018431355561023 49.46931155795932,...
476936Mondercange0208Inspire_10072018MondercangeLuxembourgEsch-sur-Alzette4.08458.7847202011.0POLYGON ((5.976497438379162 49.52610334413541,...
\n", "
" ], "text/plain": [ " POPULATION COMMUNE_1 LAU2 _subtype COMMUNE \\\n", "2 35040 Esch-sur-Alzette 0204 Inspire_10072018 Esch-sur-Alzette \n", "7 11003 Bettembourg 0201 Inspire_10072018 Bettembourg \n", "41 9098 Kayl 0206 Inspire_10072018 Kayl \n", "47 6936 Mondercange 0208 Inspire_10072018 Mondercange \n", "\n", " DISTRICT CANTON tree_count ghsl_pop light_level \\\n", "2 Luxembourg Esch-sur-Alzette 0.0 30072.804172 1370.0 \n", "7 Luxembourg Esch-sur-Alzette 1.0 11060.821753 1909.0 \n", "41 Luxembourg Esch-sur-Alzette 7.0 6947.824143 1267.0 \n", "47 Luxembourg Esch-sur-Alzette 4.0 8458.784720 2011.0 \n", "\n", " geometry \n", "2 POLYGON ((5.966652609366625 49.51287419342548,... \n", "7 POLYGON ((6.06035425169626 49.54561673366194, ... \n", "41 POLYGON ((6.018431355561023 49.46931155795932,... \n", "47 POLYGON ((5.976497438379162 49.52610334413541,... " ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db[db.touches(poly)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A note on rasters" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Very different approach. Your friend here is `rasterio`." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "p = '../data/lights.tif'\n", "src = rasterio.open(p)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "src.count" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "CRS.from_epsg(4326)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "src.crs" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BoundingBox(left=5.737499257050018, bottom=49.45416676884999, right=6.529165920550014, top=50.17916676594999)" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "src.bounds" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rioshow(src)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 4 }