From dee6b16e0f5d00c7fbc059fac08c9e1f92f0fbf2 Mon Sep 17 00:00:00 2001 From: Sian Teesdale <43341988+sianteesdale@users.noreply.github.com> Date: Thu, 26 Mar 2026 09:20:42 +0000 Subject: [PATCH] Create dedup_geogs_more.ipynb --- bin/dedup_geogs_more.ipynb | 3977 ++++++++++++++++++++++++++++++++++++ 1 file changed, 3977 insertions(+) create mode 100644 bin/dedup_geogs_more.ipynb diff --git a/bin/dedup_geogs_more.ipynb b/bin/dedup_geogs_more.ipynb new file mode 100644 index 000000000..d8e12e4b5 --- /dev/null +++ b/bin/dedup_geogs_more.ipynb @@ -0,0 +1,3977 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "3c4fa001", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import json\n", + "import urllib.request\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "id": "df2640e4", + "metadata": {}, + "source": [ + "## Process the reporting historic endpoint/dataset resource" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "47a01ee9", + "metadata": {}, + "outputs": [], + "source": [ + "datasets = ['article-4-direction-area', 'tree', 'tree-preservation-zone', 'listed-building-outline']" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "280ca866", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fetched 1000 rows...\n", + "Fetched 2000 rows...\n", + "Fetched 3000 rows...\n", + "Fetched 4000 rows...\n", + "Fetched 5000 rows...\n", + "Fetched 6000 rows...\n", + "Fetched 7000 rows...\n", + "Fetched 8000 rows...\n", + "Fetched 9000 rows...\n", + "Fetched 10000 rows...\n", + "Fetched 11000 rows...\n", + "Fetched 12000 rows...\n", + "Fetched 13000 rows...\n", + "Fetched 14000 rows...\n", + "Fetched 15000 rows...\n", + "Fetched 16000 rows...\n", + "Fetched 17000 rows...\n", + "Fetched 18000 rows...\n", + "Fetched 19000 rows...\n", + "Fetched 20000 rows...\n", + "Fetched 21000 rows...\n", + "Fetched 22000 rows...\n", + "Fetched 23000 rows...\n", + "Fetched 24000 rows...\n", + "Fetched 25000 rows...\n", + "Fetched 25548 rows...\n", + "Total: 25548 rows\n" + ] + } + ], + "source": [ + "all_rows = []\n", + "last_rowid = 0\n", + "\n", + "while True:\n", + " if last_rowid == 0:\n", + " # First batch: no filter\n", + " url = \"https://datasette.planning.data.gov.uk/performance/reporting_historic_endpoints.json?_shape=array&_size=max\"\n", + " else:\n", + " # Subsequent batches: filter by rowid__gt\n", + " url = f\"https://datasette.planning.data.gov.uk/performance/reporting_historic_endpoints.json?_shape=array&_size=max&rowid__gt={last_rowid}\"\n", + " \n", + " response = urllib.request.urlopen(url, timeout=120)\n", + " rows = json.load(response)\n", + " \n", + " if not rows:\n", + " break\n", + " \n", + " all_rows.extend(rows)\n", + " last_rowid = rows[-1]['rowid']\n", + " print(f\"Fetched {len(all_rows)} rows...\")\n", + " \n", + " if len(rows) < 1000:\n", + " break\n", + "\n", + "report_he = pd.DataFrame(all_rows)\n", + "print(f\"Total: {len(report_he)} rows\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9a6edb2a", + "metadata": {}, + "outputs": [], + "source": [ + "# Remove inactive endpoints and filter for only the 4 datasets we're interested in\n", + "report_he = report_he.loc[(report_he['dataset'].isin(datasets)) & (report_he['resource_end_date'] == '')]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "dded1fab", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'e3eb3651fdb452b7396dbf901df1f54324971d25b71355e6a5f13309a69dfc81'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "report_he.loc[(report_he['dataset'] == 'article-4-direction-area') & (report_he['name'] == 'London Borough of Barking and Dagenham')]['resource'].item()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "5a6d1834", + "metadata": {}, + "outputs": [], + "source": [ + "# Loop over and get the dataset_resource for each dataset, then concatenate into a single dataframe\n", + "dfs = []\n", + "for data in datasets:\n", + " df = pd.read_csv(f'https://datasette.planning.data.gov.uk/{data}/dataset_resource.csv?_size=max')\n", + " dfs.append(df)\n", + "\n", + "data_resource = pd.concat(dfs)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "7d230289", + "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", + "
rowidend_dateentry_datedatasetentity_countentry_countline_countmime_typeinternal_pathinternal_mime_typeresourcestart_date
4344NaNNaNarticle-4-direction-area3.034application/json;charset=ASCIINaNNaNe3eb3651fdb452b7396dbf901df1f54324971d25b71355...NaN
\n", + "
" + ], + "text/plain": [ + " rowid end_date entry_date dataset entity_count \\\n", + "43 44 NaN NaN article-4-direction-area 3.0 \n", + "\n", + " entry_count line_count mime_type internal_path \\\n", + "43 3 4 application/json;charset=ASCII NaN \n", + "\n", + " internal_mime_type resource \\\n", + "43 NaN e3eb3651fdb452b7396dbf901df1f54324971d25b71355... \n", + "\n", + " start_date \n", + "43 NaN " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data_resource.loc[data_resource['resource']=='e3eb3651fdb452b7396dbf901df1f54324971d25b71355e6a5f13309a69dfc81']" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "18d711bf", + "metadata": {}, + "outputs": [], + "source": [ + "testing = pd.merge(report_he, data_resource[['resource', 'entity_count', 'entry_count']], on='resource')\n", + "\n", + "# Groupby to get entity-count per LPA\n", + "dataset_resource_entity_count = testing.groupby(['dataset', 'name', 'organisation'])['entity_count'].sum().to_frame('dataset_resource_count').reset_index()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "140d9196", + "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", + "
rowidorganisationnameorganisation_namedatasetcollectionpipelineendpointendpoint_urldocumentation_url...latest_statuslatest_exceptionresourcelatest_log_entry_dateendpoint_entry_dateendpoint_end_dateresource_start_dateresource_end_dateentity_countentry_count
46761local-authority:BDGLondon Borough of Barking and DagenhamLondon Borough of Barking and Dagenhamarticle-4-direction-areaarticle-4-directionarticle-4-direction-area57b2b1e44cb711cb9bce7f25abf8fdfc75f8c40a9e4cd9...https://services3.arcgis.com/lCzPKKaGs7lhrnrV/...https://www.arcgis.com/home/item.html?id=b23bc......200e3eb3651fdb452b7396dbf901df1f54324971d25b71355...2026-03-242025-02-172025-02-183.03
\n", + "

1 rows × 21 columns

\n", + "
" + ], + "text/plain": [ + " rowid organisation name \\\n", + "4 6761 local-authority:BDG London Borough of Barking and Dagenham \n", + "\n", + " organisation_name dataset \\\n", + "4 London Borough of Barking and Dagenham article-4-direction-area \n", + "\n", + " collection pipeline \\\n", + "4 article-4-direction article-4-direction-area \n", + "\n", + " endpoint \\\n", + "4 57b2b1e44cb711cb9bce7f25abf8fdfc75f8c40a9e4cd9... \n", + "\n", + " endpoint_url \\\n", + "4 https://services3.arcgis.com/lCzPKKaGs7lhrnrV/... \n", + "\n", + " documentation_url ... latest_status \\\n", + "4 https://www.arcgis.com/home/item.html?id=b23bc... ... 200 \n", + "\n", + " latest_exception resource \\\n", + "4 e3eb3651fdb452b7396dbf901df1f54324971d25b71355... \n", + "\n", + " latest_log_entry_date endpoint_entry_date endpoint_end_date \\\n", + "4 2026-03-24 2025-02-17 \n", + "\n", + " resource_start_date resource_end_date entity_count entry_count \n", + "4 2025-02-18 3.0 3 \n", + "\n", + "[1 rows x 21 columns]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing.loc[(testing['dataset'] == 'article-4-direction-area') & (testing['name'] == 'London Borough of Barking and Dagenham')]" + ] + }, + { + "cell_type": "markdown", + "id": "994d5c1d", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "d5ded4db", + "metadata": {}, + "source": [ + "## Process the platform data" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "f8950663", + "metadata": {}, + "outputs": [], + "source": [ + "organisation = pd.read_csv('https://datasette.planning.data.gov.uk/digital-land/organisation.csv?_labels=on&_size=max')\n", + "\n", + "organisation = organisation[['entity', 'organisation', 'name']].rename(columns={'entity':'organisation-entity', \n", + " 'name':'organisation-name',\n", + " 'organisation':'organisation-code'})" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f313451a", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/var/folders/ff/zpylthrn3877kx4h8lxvsvjm0000gn/T/ipykernel_24654/3044584250.py:5: DtypeWarning: Columns (14,16,17,24) have mixed types. Specify dtype option on import or set low_memory=False.\n", + " df = pd.read_csv(url)\n", + "/var/folders/ff/zpylthrn3877kx4h8lxvsvjm0000gn/T/ipykernel_24654/3044584250.py:5: DtypeWarning: Columns (15,21) have mixed types. Specify dtype option on import or set low_memory=False.\n", + " df = pd.read_csv(url)\n", + "/var/folders/ff/zpylthrn3877kx4h8lxvsvjm0000gn/T/ipykernel_24654/3044584250.py:5: DtypeWarning: Columns (14,15,19) have mixed types. Specify dtype option on import or set low_memory=False.\n", + " df = pd.read_csv(url)\n" + ] + } + ], + "source": [ + "dfs = []\n", + "\n", + "for data in datasets:\n", + " url = f'https://files.planning.data.gov.uk/dataset/{data}.csv'\n", + " df = pd.read_csv(url)\n", + " dfs.append(df)\n", + "\n", + "platform_data = pd.concat(dfs)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "91a69422", + "metadata": {}, + "outputs": [], + "source": [ + "platform_data = pd.merge(platform_data, organisation, on='organisation-entity', how='left')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "52063357", + "metadata": {}, + "outputs": [], + "source": [ + "platform_entity_count = platform_data.groupby(['dataset', 'organisation-name', 'organisation-code']).size().to_frame('platform_count').reset_index()\\\n", + " .rename(columns={'organisation-name':'name', 'organisation-code':'organisation'})" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "6ed2f520", + "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", + "
datasetnameorganisationplatform_count
0article-4-direction-areaAdur District Councillocal-authority:ADU9
1article-4-direction-areaAshford Borough Councillocal-authority:ASF75
2article-4-direction-areaBirmingham City Councillocal-authority:BIR13
3article-4-direction-areaBristol City Councillocal-authority:BST16
4article-4-direction-areaBroadland District Councillocal-authority:BRO28
...............
278tree-preservation-zoneTewkesbury Borough Councillocal-authority:TEW556
279tree-preservation-zoneThanet District Councillocal-authority:THA677
280tree-preservation-zoneTorbay Councillocal-authority:TOB834
281tree-preservation-zoneWest Berkshire Councillocal-authority:WBK1115
282tree-preservation-zoneWirral Borough Councillocal-authority:WRL2458
\n", + "

283 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "0 article-4-direction-area Adur District Council \n", + "1 article-4-direction-area Ashford Borough Council \n", + "2 article-4-direction-area Birmingham City Council \n", + "3 article-4-direction-area Bristol City Council \n", + "4 article-4-direction-area Broadland District Council \n", + ".. ... ... \n", + "278 tree-preservation-zone Tewkesbury Borough Council \n", + "279 tree-preservation-zone Thanet District Council \n", + "280 tree-preservation-zone Torbay Council \n", + "281 tree-preservation-zone West Berkshire Council \n", + "282 tree-preservation-zone Wirral Borough Council \n", + "\n", + " organisation platform_count \n", + "0 local-authority:ADU 9 \n", + "1 local-authority:ASF 75 \n", + "2 local-authority:BIR 13 \n", + "3 local-authority:BST 16 \n", + "4 local-authority:BRO 28 \n", + ".. ... ... \n", + "278 local-authority:TEW 556 \n", + "279 local-authority:THA 677 \n", + "280 local-authority:TOB 834 \n", + "281 local-authority:WBK 1115 \n", + "282 local-authority:WRL 2458 \n", + "\n", + "[283 rows x 4 columns]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "platform_entity_count" + ] + }, + { + "cell_type": "markdown", + "id": "29f2fc00", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "788f65a4", + "metadata": {}, + "source": [ + "## Merge together and compare" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "67b2b88e", + "metadata": {}, + "outputs": [], + "source": [ + "testing = pd.merge(platform_entity_count, dataset_resource_entity_count, on=['dataset', 'name', 'organisation'], how='outer')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "9b2bc8e9", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datasetnameorganisationplatform_countdataset_resource_countmatch
0article-4-direction-areaAdur District Councillocal-authority:ADU9NaNmismatch
1article-4-direction-areaAshford Borough Councillocal-authority:ASF7556.0mismatch
2article-4-direction-areaBirmingham City Councillocal-authority:BIR1312.0mismatch
3article-4-direction-areaBristol City Councillocal-authority:BST16NaNmismatch
4article-4-direction-areaBroadland District Councillocal-authority:BRO28NaNmismatch
.....................
278tree-preservation-zoneTewkesbury Borough Councillocal-authority:TEW556445.0mismatch
279tree-preservation-zoneThanet District Councillocal-authority:THA677677.0match
280tree-preservation-zoneTorbay Councillocal-authority:TOB834728.0mismatch
281tree-preservation-zoneWest Berkshire Councillocal-authority:WBK1115923.0mismatch
282tree-preservation-zoneWirral Borough Councillocal-authority:WRL2458NaNmismatch
\n", + "

283 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "0 article-4-direction-area Adur District Council \n", + "1 article-4-direction-area Ashford Borough Council \n", + "2 article-4-direction-area Birmingham City Council \n", + "3 article-4-direction-area Bristol City Council \n", + "4 article-4-direction-area Broadland District Council \n", + ".. ... ... \n", + "278 tree-preservation-zone Tewkesbury Borough Council \n", + "279 tree-preservation-zone Thanet District Council \n", + "280 tree-preservation-zone Torbay Council \n", + "281 tree-preservation-zone West Berkshire Council \n", + "282 tree-preservation-zone Wirral Borough Council \n", + "\n", + " organisation platform_count dataset_resource_count match \n", + "0 local-authority:ADU 9 NaN mismatch \n", + "1 local-authority:ASF 75 56.0 mismatch \n", + "2 local-authority:BIR 13 12.0 mismatch \n", + "3 local-authority:BST 16 NaN mismatch \n", + "4 local-authority:BRO 28 NaN mismatch \n", + ".. ... ... ... ... \n", + "278 local-authority:TEW 556 445.0 mismatch \n", + "279 local-authority:THA 677 677.0 match \n", + "280 local-authority:TOB 834 728.0 mismatch \n", + "281 local-authority:WBK 1115 923.0 mismatch \n", + "282 local-authority:WRL 2458 NaN mismatch \n", + "\n", + "[283 rows x 6 columns]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b68f5857", + "metadata": {}, + "outputs": [], + "source": [ + "testing['match'] = testing.apply(lambda row: 'match' if row['platform_count'] == row['dataset_resource_count'] else 'mismatch', axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "9168dadc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "match\n", + "mismatch 230\n", + "match 53\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing['match'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "02121ec0", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datasetnameorganisationplatform_countdataset_resource_countmatch
0article-4-direction-areaAdur District Councillocal-authority:ADU9NaNmismatch
1article-4-direction-areaAshford Borough Councillocal-authority:ASF7556.0mismatch
2article-4-direction-areaBirmingham City Councillocal-authority:BIR1312.0mismatch
3article-4-direction-areaBristol City Councillocal-authority:BST16NaNmismatch
4article-4-direction-areaBroadland District Councillocal-authority:BRO28NaNmismatch
.....................
277tree-preservation-zoneTandridge District Councillocal-authority:TAN885NaNmismatch
278tree-preservation-zoneTewkesbury Borough Councillocal-authority:TEW556445.0mismatch
280tree-preservation-zoneTorbay Councillocal-authority:TOB834728.0mismatch
281tree-preservation-zoneWest Berkshire Councillocal-authority:WBK1115923.0mismatch
282tree-preservation-zoneWirral Borough Councillocal-authority:WRL2458NaNmismatch
\n", + "

230 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "0 article-4-direction-area Adur District Council \n", + "1 article-4-direction-area Ashford Borough Council \n", + "2 article-4-direction-area Birmingham City Council \n", + "3 article-4-direction-area Bristol City Council \n", + "4 article-4-direction-area Broadland District Council \n", + ".. ... ... \n", + "277 tree-preservation-zone Tandridge District Council \n", + "278 tree-preservation-zone Tewkesbury Borough Council \n", + "280 tree-preservation-zone Torbay Council \n", + "281 tree-preservation-zone West Berkshire Council \n", + "282 tree-preservation-zone Wirral Borough Council \n", + "\n", + " organisation platform_count dataset_resource_count match \n", + "0 local-authority:ADU 9 NaN mismatch \n", + "1 local-authority:ASF 75 56.0 mismatch \n", + "2 local-authority:BIR 13 12.0 mismatch \n", + "3 local-authority:BST 16 NaN mismatch \n", + "4 local-authority:BRO 28 NaN mismatch \n", + ".. ... ... ... ... \n", + "277 local-authority:TAN 885 NaN mismatch \n", + "278 local-authority:TEW 556 445.0 mismatch \n", + "280 local-authority:TOB 834 728.0 mismatch \n", + "281 local-authority:WBK 1115 923.0 mismatch \n", + "282 local-authority:WRL 2458 NaN mismatch \n", + "\n", + "[230 rows x 6 columns]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing.loc[testing['match'] == 'mismatch']" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "93080e43", + "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", + "
datasetnameorganisationplatform_countdataset_resource_countmatch
38article-4-direction-areaLondon Borough of Barking and Dagenhamlocal-authority:BDG33.0match
118listed-building-outlineLondon Borough of Barking and Dagenhamlocal-authority:BDG48NaNmismatch
\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "38 article-4-direction-area London Borough of Barking and Dagenham \n", + "118 listed-building-outline London Borough of Barking and Dagenham \n", + "\n", + " organisation platform_count dataset_resource_count match \n", + "38 local-authority:BDG 3 3.0 match \n", + "118 local-authority:BDG 48 NaN mismatch " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing.loc[testing['name'] == 'London Borough of Barking and Dagenham']" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "1ca128b5", + "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", + " \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", + " \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", + " \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", + " \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", + " \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", + "
datasetnameorganisationplatform_countdataset_resource_countmatch
164treeAshford Borough Councillocal-authority:ASF12240.0mismatch
165treeBasildon Borough Councillocal-authority:BAI549NaNmismatch
166treeBristol City Councillocal-authority:BST49614940.0mismatch
167treeBuckinghamshire Councillocal-authority:BUC7591591.0mismatch
168treeCastle Point Borough Councillocal-authority:CAS16290.0mismatch
169treeCity of Westminsterlocal-authority:WSM42860.0mismatch
170treeDartford Borough Councillocal-authority:DAR12020.0mismatch
171treeDoncaster Metropolitan Borough Councillocal-authority:DNC28320.0mismatch
172treeDover District Councillocal-authority:DOV13650.0mismatch
173treeEast Cambridgeshire District Councillocal-authority:ECA25570.0mismatch
174treeEast Riding of Yorkshire Councillocal-authority:ERY34760.0mismatch
175treeEpsom and Ewell Borough Councillocal-authority:EPS43450.0mismatch
176treeGateshead Metropolitan Borough Councillocal-authority:GAT2716NaNmismatch
177treeGloucester City Councillocal-authority:GLO13580.0mismatch
178treeHalton Borough Councillocal-authority:HAL4490.0mismatch
179treeHarlow District Councillocal-authority:HAR14670.0mismatch
180treeHorsham District Councillocal-authority:HOR7996656.0mismatch
181treeLake District National Park Authoritynational-park-authority:Q2715970420930.0mismatch
182treeLeicester City Councillocal-authority:LCE50050.0mismatch
183treeLiverpool City Councillocal-authority:LIV15710.0mismatch
184treeLondon Borough of Barnetlocal-authority:BNE61983217.0mismatch
185treeLondon Borough of Brentlocal-authority:BEN12290.0mismatch
186treeLondon Borough of Lambethlocal-authority:LBH25510.0mismatch
187treeLondon Borough of Southwarklocal-authority:SWK30350.0mismatch
188treeLondon Borough of Tower Hamletslocal-authority:TWH17690.0mismatch
189treeLondon Borough of Waltham Forestlocal-authority:WFT20430.0mismatch
190treeMaidstone Borough Councillocal-authority:MAI101260.0mismatch
191treeNew Forest District Councillocal-authority:NEW6702NaNmismatch
192treeNew Forest National Park Authoritynational-park-authority:Q7261715825742574.0match
193treeNewcastle City Councillocal-authority:NET7336NaNmismatch
194treeNorth Lincolnshire Councillocal-authority:NLN69896979.0mismatch
195treeNorth Norfolk District Councillocal-authority:NNO15090.0mismatch
196treeNorth Somerset Councillocal-authority:NSM41290.0mismatch
197treeNorthumberland County Councillocal-authority:NBL36140.0mismatch
198treePeterborough City Councillocal-authority:PTE23790.0mismatch
199treePlymouth City Councillocal-authority:PLY12520.0mismatch
200treeRossendale Borough Councillocal-authority:ROS17290.0mismatch
201treeRother District Councillocal-authority:ROH19220.0mismatch
202treeRoyal Borough of Kensington and Chelsealocal-authority:KEC45600.0mismatch
203treeSalford City Councillocal-authority:SLF12960.0mismatch
204treeSandwell Metropolitan Borough Councillocal-authority:SAW6590.0mismatch
205treeSefton Metropolitan Borough Councillocal-authority:SFT47940.0mismatch
206treeSouth Cambridgeshire District Councillocal-authority:SCA24780.0mismatch
207treeSouth Gloucestershire Councillocal-authority:SGC60860.0mismatch
208treeSouth Staffordshire Councillocal-authority:SST105050.0mismatch
209treeSpelthorne Borough Councillocal-authority:SPE3002656.0mismatch
210treeSt Albans City and District Councillocal-authority:SAL34770.0mismatch
211treeStockport Metropolitan Borough Councillocal-authority:SKP81770.0mismatch
212treeSwale Borough Councillocal-authority:SWL15960.0mismatch
213treeTandridge District Councillocal-authority:TAN16780.0mismatch
214treeTewkesbury Borough Councillocal-authority:TEW20320.0mismatch
215treeThanet District Councillocal-authority:THA18950.0mismatch
216treeTorbay Councillocal-authority:TOB20790.0mismatch
217treeWest Berkshire Councillocal-authority:WBK65720.0mismatch
218treeWirral Borough Councillocal-authority:WRL44170.0mismatch
\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "164 tree Ashford Borough Council \n", + "165 tree Basildon Borough Council \n", + "166 tree Bristol City Council \n", + "167 tree Buckinghamshire Council \n", + "168 tree Castle Point Borough Council \n", + "169 tree City of Westminster \n", + "170 tree Dartford Borough Council \n", + "171 tree Doncaster Metropolitan Borough Council \n", + "172 tree Dover District Council \n", + "173 tree East Cambridgeshire District Council \n", + "174 tree East Riding of Yorkshire Council \n", + "175 tree Epsom and Ewell Borough Council \n", + "176 tree Gateshead Metropolitan Borough Council \n", + "177 tree Gloucester City Council \n", + "178 tree Halton Borough Council \n", + "179 tree Harlow District Council \n", + "180 tree Horsham District Council \n", + "181 tree Lake District National Park Authority \n", + "182 tree Leicester City Council \n", + "183 tree Liverpool City Council \n", + "184 tree London Borough of Barnet \n", + "185 tree London Borough of Brent \n", + "186 tree London Borough of Lambeth \n", + "187 tree London Borough of Southwark \n", + "188 tree London Borough of Tower Hamlets \n", + "189 tree London Borough of Waltham Forest \n", + "190 tree Maidstone Borough Council \n", + "191 tree New Forest District Council \n", + "192 tree New Forest National Park Authority \n", + "193 tree Newcastle City Council \n", + "194 tree North Lincolnshire Council \n", + "195 tree North Norfolk District Council \n", + "196 tree North Somerset Council \n", + "197 tree Northumberland County Council \n", + "198 tree Peterborough City Council \n", + "199 tree Plymouth City Council \n", + "200 tree Rossendale Borough Council \n", + "201 tree Rother District Council \n", + "202 tree Royal Borough of Kensington and Chelsea \n", + "203 tree Salford City Council \n", + "204 tree Sandwell Metropolitan Borough Council \n", + "205 tree Sefton Metropolitan Borough Council \n", + "206 tree South Cambridgeshire District Council \n", + "207 tree South Gloucestershire Council \n", + "208 tree South Staffordshire Council \n", + "209 tree Spelthorne Borough Council \n", + "210 tree St Albans City and District Council \n", + "211 tree Stockport Metropolitan Borough Council \n", + "212 tree Swale Borough Council \n", + "213 tree Tandridge District Council \n", + "214 tree Tewkesbury Borough Council \n", + "215 tree Thanet District Council \n", + "216 tree Torbay Council \n", + "217 tree West Berkshire Council \n", + "218 tree Wirral Borough Council \n", + "\n", + " organisation platform_count \\\n", + "164 local-authority:ASF 1224 \n", + "165 local-authority:BAI 549 \n", + "166 local-authority:BST 4961 \n", + "167 local-authority:BUC 7591 \n", + "168 local-authority:CAS 1629 \n", + "169 local-authority:WSM 4286 \n", + "170 local-authority:DAR 1202 \n", + "171 local-authority:DNC 2832 \n", + "172 local-authority:DOV 1365 \n", + "173 local-authority:ECA 2557 \n", + "174 local-authority:ERY 3476 \n", + "175 local-authority:EPS 4345 \n", + "176 local-authority:GAT 2716 \n", + "177 local-authority:GLO 1358 \n", + "178 local-authority:HAL 449 \n", + "179 local-authority:HAR 1467 \n", + "180 local-authority:HOR 7996 \n", + "181 national-park-authority:Q27159704 2093 \n", + "182 local-authority:LCE 5005 \n", + "183 local-authority:LIV 1571 \n", + "184 local-authority:BNE 6198 \n", + "185 local-authority:BEN 1229 \n", + "186 local-authority:LBH 2551 \n", + "187 local-authority:SWK 3035 \n", + "188 local-authority:TWH 1769 \n", + "189 local-authority:WFT 2043 \n", + "190 local-authority:MAI 10126 \n", + "191 local-authority:NEW 6702 \n", + "192 national-park-authority:Q72617158 2574 \n", + "193 local-authority:NET 7336 \n", + "194 local-authority:NLN 6989 \n", + "195 local-authority:NNO 1509 \n", + "196 local-authority:NSM 4129 \n", + "197 local-authority:NBL 3614 \n", + "198 local-authority:PTE 2379 \n", + "199 local-authority:PLY 1252 \n", + "200 local-authority:ROS 1729 \n", + "201 local-authority:ROH 1922 \n", + "202 local-authority:KEC 4560 \n", + "203 local-authority:SLF 1296 \n", + "204 local-authority:SAW 659 \n", + "205 local-authority:SFT 4794 \n", + "206 local-authority:SCA 2478 \n", + "207 local-authority:SGC 6086 \n", + "208 local-authority:SST 10505 \n", + "209 local-authority:SPE 300 \n", + "210 local-authority:SAL 3477 \n", + "211 local-authority:SKP 8177 \n", + "212 local-authority:SWL 1596 \n", + "213 local-authority:TAN 1678 \n", + "214 local-authority:TEW 2032 \n", + "215 local-authority:THA 1895 \n", + "216 local-authority:TOB 2079 \n", + "217 local-authority:WBK 6572 \n", + "218 local-authority:WRL 4417 \n", + "\n", + " dataset_resource_count match \n", + "164 0.0 mismatch \n", + "165 NaN mismatch \n", + "166 4940.0 mismatch \n", + "167 591.0 mismatch \n", + "168 0.0 mismatch \n", + "169 0.0 mismatch \n", + "170 0.0 mismatch \n", + "171 0.0 mismatch \n", + "172 0.0 mismatch \n", + "173 0.0 mismatch \n", + "174 0.0 mismatch \n", + "175 0.0 mismatch \n", + "176 NaN mismatch \n", + "177 0.0 mismatch \n", + "178 0.0 mismatch \n", + "179 0.0 mismatch \n", + "180 656.0 mismatch \n", + "181 0.0 mismatch \n", + "182 0.0 mismatch \n", + "183 0.0 mismatch \n", + "184 3217.0 mismatch \n", + "185 0.0 mismatch \n", + "186 0.0 mismatch \n", + "187 0.0 mismatch \n", + "188 0.0 mismatch \n", + "189 0.0 mismatch \n", + "190 0.0 mismatch \n", + "191 NaN mismatch \n", + "192 2574.0 match \n", + "193 NaN mismatch \n", + "194 6979.0 mismatch \n", + "195 0.0 mismatch \n", + "196 0.0 mismatch \n", + "197 0.0 mismatch \n", + "198 0.0 mismatch \n", + "199 0.0 mismatch \n", + "200 0.0 mismatch \n", + "201 0.0 mismatch \n", + "202 0.0 mismatch \n", + "203 0.0 mismatch \n", + "204 0.0 mismatch \n", + "205 0.0 mismatch \n", + "206 0.0 mismatch \n", + "207 0.0 mismatch \n", + "208 0.0 mismatch \n", + "209 2656.0 mismatch \n", + "210 0.0 mismatch \n", + "211 0.0 mismatch \n", + "212 0.0 mismatch \n", + "213 0.0 mismatch \n", + "214 0.0 mismatch \n", + "215 0.0 mismatch \n", + "216 0.0 mismatch \n", + "217 0.0 mismatch \n", + "218 0.0 mismatch " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing.loc[testing['dataset'] == 'tree']" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "20bd0fdd", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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YL///vs/rpJnRKyQAwAAAACOWOnSpW3+/Pk2ffp0W7p0qXXr1s33he+feq795kuWLLHffvvN9uzZ49XVtae8cePGHtT/+OOP9tprr/n+84yOgBwAAAAAcMRuu+02a9KkiV1zzTVWrVo127hxY7LVclExOLVDU1uzggULegCuVXOluBcqVMguvvhi36Ou4nHas57RZdq3b98+y8C2bNnifeo2b95sefLkCX06AJDxdU+wuNB9c+gzAACkAzt37rQVK1Z4xfEcOXKEPh2k0mt7qHEoK+QAAAAAAARAQA4AAAAAQAAE5AAAAAAABEBADgAAAABAAATkAAAAAAAEQEAOAAAAAEAABOQAAAAAAARAQA4AAAAAQAAE5AAAAAAABEBADgAAAAA4YjNnzrRMmTLZpk2b0t2/ZqZMmWzSpEmp/nezpPpfBAAAAACYdU9I3X+F7ptT9NfXrFnT1q5dawkJqfzflcRPP/1kpUqVsi+++MLOOOMMS+sIyAEAAAAARyxbtmyWmJjIv2R6SVkvWbKkpwbsf2vbtq0/vnPnTv++QIEClitXLmvatKmtX78+5CkDAAAAQFyoXbu2tWvXzjp06GD58uWzwoUL27Bhw2z79u3WsmVLy507t51yyik2derUA6as//zzz9aoUSP/2eOOO84qVKhg77zzTrLnTp8+3SpXrmw5c+a0unXr2oYNG/z3lS9f3vLkyWPXXXed7dixI3ZO06ZNs1q1alnevHk9Trz00ktt+fLlsce1Oi76nfr9+m+IjBgxws8he/bsVqRIEbvzzjuT/ff+9ttvdsUVV9ixxx5rpUuXtsmTJ2fsgHzevHme0hDd3nvvPT9+1VVX+deOHTvaW2+9ZRMnTrRZs2bZmjVrrEmTJiFPGQAAAADixujRo+3444+3uXPnenDepk0bj9eUnr5w4UKrX7++3XjjjcmC5ogWV3ft2mUfffSRff311/bEE0/4QmtS3bt3t2effdY+++wzW7VqlV199dXWv39/Gzt2rL399tv27rvv2sCBA2PP12RAp06dbP78+TZjxgzLnDmzB9F79+71x3We8v7773uM+frrr/v9IUOG+Pm0bt3az0XBtiYTkurRo4f//UWLFtnFF19s119/vf3++++WkjLt27dvn6URmnmZMmWKLVu2zLZs2WIFCxb0F+LKK6/0x7///nufKZk9e7ZVr179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VqhQwXbv3h36FJFGEJAjmA0bNtgLL7zgs4YKxHPnzm1PPfWUv2mNGDHCbr/9dl4dIOAK+Y4dO3xG/9FHH/UMFk2gffjhhz67X6VKFd9iwoACCEfbSIoUKeKflz/++KOVLVvWJ7k1kSZLlizh5QECUcbKihUrrESJEvb22297FqiuzVtuucV27drlk93z58/n9QEBOcJJSEiwc88911Pt1q9f7wP+Bg0aeAq70u00g9iiRQteIiDgHvKNGzf6tanA/Oqrr7YnnnjCM1p27txpw4cPt++//57XBwhE16G2j2iirF69enbJJZd4eqx8/vnndtddd/kqOoCU/7w8UKbZKaecYoMGDbIbb7zRnnzyydhi088//2zvvvuurVmzhpcGBOQIJ3v27P7GpCJREydOtMKFC/tquSpQFi1a1M4880z76KOPeLMCAgwmNJDIlSuX5c+f36644gpr3LixDRgwIDaY+P333238+PH21Vdf8foAgdonVa5c2SpVquT1HVQs6rnnnrNjjjnGH5s8ebL9+eefnn0GIHUKoGqC7I8//vDv8+XL55Nkyga9+OKLrXXr1n588+bNvvC0detWfxygyjpStYDbokWLbPHixf69qqmfdtpp/piK0Wzfvt2DclHVdaX2tG/fnorOQCoOJpTieuyxx3ogftxxx9mDDz5obdq08f1uLVu29OdoEKGUO1271113Ha8PkIrV1LXyrb2o2t6lrDJlrPzwww/+uB7T9fzGG294OqyeX6hQIV4fIAUlraY+btw4n8zWGPfll1/2mkjaotm7d2+fINP1qQltBe0LFizwCTRaiSLTPjrWI5W89tprHmBrL40G+nPmzLEXX3zRV9+mTZvmXzWDmCVLFi/wNnv2bCtfvjyvD5BKOnfubJMmTfKsFO1D1a1mzZqeAqvBhKrDFi9e3Gf3NbCYO3euZc2a1f7666/YqhyAlKFq6trGdc011/gqnAb5J510kk2YMMGGDh3q273UWkmBgDLNtO3r9NNP5+UAUkjSQFoZYxrjqhaS9o2ryKKKKyroFgXnCxcutC1btvg1qkBd493/9//+n39FfCMgR6rQm5D2oapdklJe582b5+2TVB1We1K14qb0OlWiPP744+2BBx7wNDwAKUNzsUlbm2lFrUOHDh58qzjUK6+84gF4ly5dvNaDMluUDqvJtBNOOMFX5RhMAKlD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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "f, ax = plt.subplots(figsize=(12, 6))\n", + "\n", + "data = testing.groupby(['dataset', 'match']).size().unstack(fill_value=0)\n", + "\n", + "data.plot(kind='bar', ax=ax)\n", + "plt.xticks(rotation=45, ha='right')\n", + "\n", + "ax.set_ylabel('Count')\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "67f40c81", + "metadata": {}, + "source": [ + "---\n", + "## Randomly check resources\n", + "\n", + "Take ten resources at random and investigate them to get a sample of the problems.\n", + "\n", + "Some things to check for each:\n", + "\n", + "1. the entity_count of the platform vs the dataset_resource entity_count. If they are equal then all is good\n", + "2. if they are not equal then download the transformed_resource (I can probably give you the link structure to follow) and download the entities  from the platform. Get the entities that aren’t in the resource but are on the platform. you can then look at these entities to check the history of what’s going on.\n", + "3. check the entity_count on the dataset_resource is equal to the entity_count in the transformed resource. This wil tell us if there’s a processing issue\n", + "\n", + "the link to transformed resources wil be something like:\n", + "files.planning.data.gov.uk/-collection/transformed//.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "20ee654b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['47b2c02399036050fe507e4b90ee532f25293b19f7cec9fb308336e625f7109b',\n", + " '3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8b085d413931ee21109',\n", + " 'bb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b32fd08f4c8614efc5e',\n", + " '6eb49d0579ac5162126f793800ead81a74761b880e4066fc623a01ec72678952',\n", + " '5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4ff982356df89fa1787',\n", + " '8b88687d996f7b9bbcfae4f4ba7c515f55eef34212a0064eb922891d3c99a97e',\n", + " 'd632df6f6b49074036d830502a8f22df6b3e75593d9a8cd783d4ccf33d6dd67a',\n", + " 'dd14d735a5cc249c6a3c4751e134c2040a83e58aa0c29475faed0825b54c2927',\n", + " 'ae9aa5602c72b8a76da0eac063f7190e9211fd198244e244c89d65b41306a192',\n", + " '85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6add3cf010243303ef95']" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Get a random sample of 10 resources\n", + "sample_df = report_he.sample(n=10, random_state=42)\n", + "sample_resources = sample_df['resource'].tolist()\n", + "\n", + "sample_resources" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "b09eba1f", + "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", + " \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", + " \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", + "
rowidorganisationnameorganisation_namedatasetcollectionpipelineendpointendpoint_urldocumentation_urllicencelatest_statuslatest_exceptionresourcelatest_log_entry_dateendpoint_entry_dateendpoint_end_dateresource_start_dateresource_end_date
1485414855local-authority:GLOGloucester City CouncilGloucester City Councillisted-building-outlinelisted-buildinglisted-building-outlinef569cf738abb48f8d9d2bda008b5e27716877dd84a22fa...https://gcty.dynamicmaps.co.uk:8443/geoserver/...https://www.gloucester.gov.uk/planning-develop...ogl320047b2c02399036050fe507e4b90ee532f25293b19f7cec9...2026-03-242024-08-132024-09-21
1486514866local-authority:GLOGloucester City CouncilGloucester City Counciltreetree-preservation-ordertree599237e24ea953f431090df305657e05d78d64e6e33adc...https://gcty.dynamicmaps.co.uk:8443/geoserver/...https://www.gloucester.gov.uk/environment-wast...ogl32003081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8...2026-03-242024-08-122024-08-13
2060920610local-authority:ROSRossendale Borough CouncilRossendale Borough Councillisted-building-outlinelisted-buildinglisted-building-outline3da95e36b0c049a66afc06990be03fb14cf070a24ae89f...https://www.rossendale.gov.uk/downloads/file/1...https://www.rossendale.gov.uk/heritage/heritag...ogl3200bb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b...2026-03-242025-12-012025-12-02
1701917020local-authority:LCELeicester City CouncilLeicester City Counciltree-preservation-zonetree-preservation-ordertree-preservation-zone381e46f1261f1edd7d67238973f01c8021cf675f65f493...https://geoserver.leicester.gov.uk/geoserver/O...https://data.leicester.gov.uk/explore/?sort=mo...ogl32006eb49d0579ac5162126f793800ead81a74761b880e4066...2026-03-242025-09-292026-03-24
2448024481local-authority:WFTLondon Borough of Waltham ForestLondon Borough of Waltham Foresttree-preservation-zonetree-preservation-ordertree-preservation-zonec18514d51a4072b1fa0eceb0e390e65555bfcc93135b37...https://walthamforest.statmap.co.uk/map/wfs.sv...https://www.walthamforest.gov.uk/neighbourhood...ogl32005837666a86b654bdf27164f2fa5bdc6c74552efccda5c4...2026-03-242026-01-202026-01-21
2222022221local-authority:TANTandridge District CouncilTandridge District Councilarticle-4-direction-areaarticle-4-directionarticle-4-direction-area51020cd616333d91260a1bad500167d9cc02e85fb50c19...https://services8.arcgis.com/DOopK66xzdr2Avop/...https://tdcmaps.tandridge.gov.uk/odp_data/odp_...ogl32008b88687d996f7b9bbcfae4f4ba7c515f55eef34212a006...2026-03-242026-02-202026-02-21
1435214353local-authority:EPSEpsom and Ewell Borough CouncilEpsom and Ewell Borough Councillisted-building-outlinelisted-buildinglisted-building-outlineb64e3b0edc13c75c0a21a459c13c7c9c6eb89e0785885c...https://maps.epsom-ewell.gov.uk/getows.ashx?ma...https://www.epsom-ewell.gov.uk/residents/plann...200d632df6f6b49074036d830502a8f22df6b3e75593d9a8c...2026-03-242023-12-182026-02-14
67876788local-authority:BDGLondon Borough of Barking and DagenhamLondon Borough of Barking and Dagenhamlisted-building-outlinelisted-buildinglisted-building-outline6a183d1c8b8505b27532c8335137139be5b8cdb97f8c2a...https://services3.arcgis.com/lCzPKKaGs7lhrnrV/...https://www.arcgis.com/home/item.html?id=8421a...ogl3200dd14d735a5cc249c6a3c4751e134c2040a83e58aa0c294...2026-03-242025-02-182025-02-19
2282422825local-authority:TWHLondon Borough of Tower HamletsLondon Borough of Tower Hamletstreetree-preservation-ordertreeeaceade72cd00741743fba9921fb2ef764ed3363f882f4...https://services1.arcgis.com/KZuCGRSe2K5BiG1Z/...https://www.towerhamlets.gov.uk/lgnl/planning_...ogl3200ae9aa5602c72b8a76da0eac063f7190e9211fd198244e2...2026-03-242025-01-022025-12-02
2476724768local-authority:WOXWest Oxfordshire District CouncilWest Oxfordshire District Councilarticle-4-direction-areaarticle-4-directionarticle-4-direction-area5a762b7a74f89910bb2f3afabf06410827b52428f21a59...https://services5.arcgis.com/z8GJkxrWic0alJoM/...https://www.westoxon.gov.uk/planning-and-build...ogl320085e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6a...2026-03-242026-01-162026-01-17
\n", + "
" + ], + "text/plain": [ + " rowid organisation name \\\n", + "14854 14855 local-authority:GLO Gloucester City Council \n", + "14865 14866 local-authority:GLO Gloucester City Council \n", + "20609 20610 local-authority:ROS Rossendale Borough Council \n", + "17019 17020 local-authority:LCE Leicester City Council \n", + "24480 24481 local-authority:WFT London Borough of Waltham Forest \n", + "22220 22221 local-authority:TAN Tandridge District Council \n", + "14352 14353 local-authority:EPS Epsom and Ewell Borough Council \n", + "6787 6788 local-authority:BDG London Borough of Barking and Dagenham \n", + "22824 22825 local-authority:TWH London Borough of Tower Hamlets \n", + "24767 24768 local-authority:WOX West Oxfordshire District Council \n", + "\n", + " organisation_name dataset \\\n", + "14854 Gloucester City Council listed-building-outline \n", + "14865 Gloucester City Council tree \n", + "20609 Rossendale Borough Council listed-building-outline \n", + "17019 Leicester City Council tree-preservation-zone \n", + "24480 London Borough of Waltham Forest tree-preservation-zone \n", + "22220 Tandridge District Council article-4-direction-area \n", + "14352 Epsom and Ewell Borough Council listed-building-outline \n", + "6787 London Borough of Barking and Dagenham listed-building-outline \n", + "22824 London Borough of Tower Hamlets tree \n", + "24767 West Oxfordshire District Council article-4-direction-area \n", + "\n", + " collection pipeline \\\n", + "14854 listed-building listed-building-outline \n", + "14865 tree-preservation-order tree \n", + "20609 listed-building listed-building-outline \n", + "17019 tree-preservation-order tree-preservation-zone \n", + "24480 tree-preservation-order tree-preservation-zone \n", + "22220 article-4-direction article-4-direction-area \n", + "14352 listed-building listed-building-outline \n", + "6787 listed-building listed-building-outline \n", + "22824 tree-preservation-order tree \n", + "24767 article-4-direction article-4-direction-area \n", + "\n", + " endpoint \\\n", + "14854 f569cf738abb48f8d9d2bda008b5e27716877dd84a22fa... \n", + "14865 599237e24ea953f431090df305657e05d78d64e6e33adc... \n", + "20609 3da95e36b0c049a66afc06990be03fb14cf070a24ae89f... \n", + "17019 381e46f1261f1edd7d67238973f01c8021cf675f65f493... \n", + "24480 c18514d51a4072b1fa0eceb0e390e65555bfcc93135b37... \n", + "22220 51020cd616333d91260a1bad500167d9cc02e85fb50c19... \n", + "14352 b64e3b0edc13c75c0a21a459c13c7c9c6eb89e0785885c... \n", + "6787 6a183d1c8b8505b27532c8335137139be5b8cdb97f8c2a... \n", + "22824 eaceade72cd00741743fba9921fb2ef764ed3363f882f4... \n", + "24767 5a762b7a74f89910bb2f3afabf06410827b52428f21a59... \n", + "\n", + " endpoint_url \\\n", + "14854 https://gcty.dynamicmaps.co.uk:8443/geoserver/... \n", + "14865 https://gcty.dynamicmaps.co.uk:8443/geoserver/... \n", + "20609 https://www.rossendale.gov.uk/downloads/file/1... \n", + "17019 https://geoserver.leicester.gov.uk/geoserver/O... \n", + "24480 https://walthamforest.statmap.co.uk/map/wfs.sv... \n", + "22220 https://services8.arcgis.com/DOopK66xzdr2Avop/... \n", + "14352 https://maps.epsom-ewell.gov.uk/getows.ashx?ma... \n", + "6787 https://services3.arcgis.com/lCzPKKaGs7lhrnrV/... \n", + "22824 https://services1.arcgis.com/KZuCGRSe2K5BiG1Z/... \n", + "24767 https://services5.arcgis.com/z8GJkxrWic0alJoM/... \n", + "\n", + " documentation_url licence \\\n", + "14854 https://www.gloucester.gov.uk/planning-develop... ogl3 \n", + "14865 https://www.gloucester.gov.uk/environment-wast... ogl3 \n", + "20609 https://www.rossendale.gov.uk/heritage/heritag... ogl3 \n", + "17019 https://data.leicester.gov.uk/explore/?sort=mo... ogl3 \n", + "24480 https://www.walthamforest.gov.uk/neighbourhood... ogl3 \n", + "22220 https://tdcmaps.tandridge.gov.uk/odp_data/odp_... ogl3 \n", + "14352 https://www.epsom-ewell.gov.uk/residents/plann... \n", + "6787 https://www.arcgis.com/home/item.html?id=8421a... ogl3 \n", + "22824 https://www.towerhamlets.gov.uk/lgnl/planning_... ogl3 \n", + "24767 https://www.westoxon.gov.uk/planning-and-build... ogl3 \n", + "\n", + " latest_status latest_exception \\\n", + "14854 200 \n", + "14865 200 \n", + "20609 200 \n", + "17019 200 \n", + "24480 200 \n", + "22220 200 \n", + "14352 200 \n", + "6787 200 \n", + "22824 200 \n", + "24767 200 \n", + "\n", + " resource \\\n", + "14854 47b2c02399036050fe507e4b90ee532f25293b19f7cec9... \n", + "14865 3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8... \n", + "20609 bb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b... \n", + "17019 6eb49d0579ac5162126f793800ead81a74761b880e4066... \n", + "24480 5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4... \n", + "22220 8b88687d996f7b9bbcfae4f4ba7c515f55eef34212a006... \n", + "14352 d632df6f6b49074036d830502a8f22df6b3e75593d9a8c... \n", + "6787 dd14d735a5cc249c6a3c4751e134c2040a83e58aa0c294... \n", + "22824 ae9aa5602c72b8a76da0eac063f7190e9211fd198244e2... \n", + "24767 85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6a... \n", + "\n", + " latest_log_entry_date endpoint_entry_date endpoint_end_date \\\n", + "14854 2026-03-24 2024-08-13 \n", + "14865 2026-03-24 2024-08-12 \n", + "20609 2026-03-24 2025-12-01 \n", + "17019 2026-03-24 2025-09-29 \n", + "24480 2026-03-24 2026-01-20 \n", + "22220 2026-03-24 2026-02-20 \n", + "14352 2026-03-24 2023-12-18 \n", + "6787 2026-03-24 2025-02-18 \n", + "22824 2026-03-24 2025-01-02 \n", + "24767 2026-03-24 2026-01-16 \n", + "\n", + " resource_start_date resource_end_date \n", + "14854 2024-09-21 \n", + "14865 2024-08-13 \n", + "20609 2025-12-02 \n", + "17019 2026-03-24 \n", + "24480 2026-01-21 \n", + "22220 2026-02-21 \n", + "14352 2026-02-14 \n", + "6787 2025-02-19 \n", + "22824 2025-12-02 \n", + "24767 2026-01-17 " + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sample_df" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "f5d98784", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
rowidend_dateentry_datedatasetentity_countentry_countline_countmime_typeinternal_pathinternal_mime_typeresourcestart_date
407408NaNNaNarticle-4-direction-area84.08485application/json;charset=ASCIINaNNaN85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6a...NaN
3738NaNNaNtreeNaN13581359application/xml;charset=ASCIINaNNaN3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8...NaN
744745NaNNaNtreeNaN16771678application/json;charset=ASCIINaNNaNae9aa5602c72b8a76da0eac063f7190e9211fd198244e2...NaN
972973NaNNaNtree-preservation-zone217.0217218application/xml;charset=ASCIINaNNaN5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4...NaN
159160NaNNaNlisted-building-outlineNaN278279text/csv;charset=ASCIINaNNaNbb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b...NaN
\n", + "
" + ], + "text/plain": [ + " rowid end_date entry_date dataset entity_count \\\n", + "407 408 NaN NaN article-4-direction-area 84.0 \n", + "37 38 NaN NaN tree NaN \n", + "744 745 NaN NaN tree NaN \n", + "972 973 NaN NaN tree-preservation-zone 217.0 \n", + "159 160 NaN NaN listed-building-outline NaN \n", + "\n", + " entry_count line_count mime_type internal_path \\\n", + "407 84 85 application/json;charset=ASCII NaN \n", + "37 1358 1359 application/xml;charset=ASCII NaN \n", + "744 1677 1678 application/json;charset=ASCII NaN \n", + "972 217 218 application/xml;charset=ASCII NaN \n", + "159 278 279 text/csv;charset=ASCII NaN \n", + "\n", + " internal_mime_type resource \\\n", + "407 NaN 85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6a... \n", + "37 NaN 3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8... \n", + "744 NaN ae9aa5602c72b8a76da0eac063f7190e9211fd198244e2... \n", + "972 NaN 5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4... \n", + "159 NaN bb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b... \n", + "\n", + " start_date \n", + "407 NaN \n", + "37 NaN \n", + "744 NaN \n", + "972 NaN \n", + "159 NaN " + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check the entity_counts for these resources in the dataset_resource table\n", + "data_resource.loc[data_resource['resource'].isin(sample_resources)].head(10)" + ] + }, + { + "cell_type": "markdown", + "id": "bab92a8d", + "metadata": {}, + "source": [ + "Only 5 out of the 10 resources are showing.\n", + "\n", + "| Resource | Dataset | LPA | dataset_resource entity_count | platform entity_count | transformed resource entity_count |\n", + "| ----- | ------ | ----- | ------ | ---- | ---- |\n", + "| 47b2c02399036050fe507e4b90ee532f25293b19f7cec9fb308336e625f7109b | LBO | Gloucester City | Missing | 486 | 486\n", + "| 6eb49d0579ac5162126f793800ead81a74761b880e4066fc623a01ec72678952 | TPZ | Leicester City | Missing | 146 | 146 |\n", + "| 8b88687d996f7b9bbcfae4f4ba7c515f55eef34212a0064eb922891d3c99a97e | A4D | Tandridge | Missing | 50 | 50\n", + "| d632df6f6b49074036d830502a8f22df6b3e75593d9a8cd783d4ccf33d6dd67a | LBO | Epsom and Ewell | Missing | 272 | 272\n", + "| dd14d735a5cc249c6a3c4751e134c2040a83e58aa0c29475faed0825b54c2927 | LBO | Barking and Dagenham | Missing | 48 | 48\n", + "| 3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8b085d413931ee21109 | Tree | Gloucester City | No entity recorded | 1358 | 1358\n", + "| ae9aa5602c72b8a76da0eac063f7190e9211fd198244e244c89d65b41306a192 | Tree | Tower Hamlets | No entity recorded | 1769 | 1677\n", + "| bb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b32fd08f4c8614efc5e | LBO | Rossendale | No entity recorded | 278 | 278\n", + "| 85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6add3cf010243303ef95 | A4D | West Oxfordshire | 84 | 84 | n/a |\n", + "| 5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4ff982356df89fa1787 | TPZ | Waltham Forest | 217 | 217 | n/a |\n", + "\n", + "Let's first investigate the platform entity counts now.\n", + "\n", + "https://files.planning.data.gov.uk/listed-building-collection/transformed/listed-building-outline/6df5bd01605beb5eec759d8b451d5a7a699b65edb6af10baaea10bab85ece59c.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "583ca0bf", + "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", + "
datasetnameorganisationplatform_count
0article-4-direction-areaAdur District Councillocal-authority:ADU9
1article-4-direction-areaAshford Borough Councillocal-authority:ASF75
2article-4-direction-areaBirmingham City Councillocal-authority:BIR13
3article-4-direction-areaBristol City Councillocal-authority:BST16
4article-4-direction-areaBroadland District Councillocal-authority:BRO28
...............
278tree-preservation-zoneTewkesbury Borough Councillocal-authority:TEW556
279tree-preservation-zoneThanet District Councillocal-authority:THA677
280tree-preservation-zoneTorbay Councillocal-authority:TOB834
281tree-preservation-zoneWest Berkshire Councillocal-authority:WBK1115
282tree-preservation-zoneWirral Borough Councillocal-authority:WRL2458
\n", + "

283 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "0 article-4-direction-area Adur District Council \n", + "1 article-4-direction-area Ashford Borough Council \n", + "2 article-4-direction-area Birmingham City Council \n", + "3 article-4-direction-area Bristol City Council \n", + "4 article-4-direction-area Broadland District Council \n", + ".. ... ... \n", + "278 tree-preservation-zone Tewkesbury Borough Council \n", + "279 tree-preservation-zone Thanet District Council \n", + "280 tree-preservation-zone Torbay Council \n", + "281 tree-preservation-zone West Berkshire Council \n", + "282 tree-preservation-zone Wirral Borough Council \n", + "\n", + " organisation platform_count \n", + "0 local-authority:ADU 9 \n", + "1 local-authority:ASF 75 \n", + "2 local-authority:BIR 13 \n", + "3 local-authority:BST 16 \n", + "4 local-authority:BRO 28 \n", + ".. ... ... \n", + "278 local-authority:TEW 556 \n", + "279 local-authority:THA 677 \n", + "280 local-authority:TOB 834 \n", + "281 local-authority:WBK 1115 \n", + "282 local-authority:WRL 2458 \n", + "\n", + "[283 rows x 4 columns]" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "platform_entity_count" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "e440903e", + "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", + "
collectiondatasetresourceplatform_count
0listed-buildinglisted-building-outline47b2c02399036050fe507e4b90ee532f25293b19f7cec9...486
1tree-preservation-ordertree3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8...1358
2listed-buildinglisted-building-outlinebb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b...278
3tree-preservation-ordertree-preservation-zone6eb49d0579ac5162126f793800ead81a74761b880e4066...146
4tree-preservation-ordertree-preservation-zone5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4...217
5article-4-directionarticle-4-direction-area8b88687d996f7b9bbcfae4f4ba7c515f55eef34212a006...50
6listed-buildinglisted-building-outlined632df6f6b49074036d830502a8f22df6b3e75593d9a8c...272
7listed-buildinglisted-building-outlinedd14d735a5cc249c6a3c4751e134c2040a83e58aa0c294...48
8tree-preservation-ordertreeae9aa5602c72b8a76da0eac063f7190e9211fd198244e2...1769
9article-4-directionarticle-4-direction-area85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6a...84
\n", + "
" + ], + "text/plain": [ + " collection dataset \\\n", + "0 listed-building listed-building-outline \n", + "1 tree-preservation-order tree \n", + "2 listed-building listed-building-outline \n", + "3 tree-preservation-order tree-preservation-zone \n", + "4 tree-preservation-order tree-preservation-zone \n", + "5 article-4-direction article-4-direction-area \n", + "6 listed-building listed-building-outline \n", + "7 listed-building listed-building-outline \n", + "8 tree-preservation-order tree \n", + "9 article-4-direction article-4-direction-area \n", + "\n", + " resource platform_count \n", + "0 47b2c02399036050fe507e4b90ee532f25293b19f7cec9... 486 \n", + "1 3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8... 1358 \n", + "2 bb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b... 278 \n", + "3 6eb49d0579ac5162126f793800ead81a74761b880e4066... 146 \n", + "4 5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4... 217 \n", + "5 8b88687d996f7b9bbcfae4f4ba7c515f55eef34212a006... 50 \n", + "6 d632df6f6b49074036d830502a8f22df6b3e75593d9a8c... 272 \n", + "7 dd14d735a5cc249c6a3c4751e134c2040a83e58aa0c294... 48 \n", + "8 ae9aa5602c72b8a76da0eac063f7190e9211fd198244e2... 1769 \n", + "9 85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6a... 84 " + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result = sample_df.merge(\n", + " platform_entity_count,\n", + " on=['name', 'dataset'], how='inner')\n", + "\n", + "result[['collection', 'dataset', 'resource', 'platform_count']]" + ] + }, + { + "cell_type": "markdown", + "id": "a9dfb614", + "metadata": {}, + "source": [ + "So the two resources that had entities - 85e... and 583... - matches the platform data. But what's happened to the other 8?\n", + "\n", + "Let's use the link to transformed resources:\n", + "files.planning.data.gov.uk/-collection/transformed//.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "e9d1e556", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Resource: 47b2c02399036050fe507e4b90ee532f25293b19f7cec9fb308336e625f7109b, Unique Entities: 486\n", + "Resource: 3081bb2dec818694e2a6eaccd39ad37abc7dca39131dd8b085d413931ee21109, Unique Entities: 1358\n", + "Resource: bb6a8eb7e6f4720030aec3bd5fdff525700d8ae045cd7b32fd08f4c8614efc5e, Unique Entities: 278\n", + "Resource: 6eb49d0579ac5162126f793800ead81a74761b880e4066fc623a01ec72678952, Unique Entities: 146\n", + "Resource: 5837666a86b654bdf27164f2fa5bdc6c74552efccda5c4ff982356df89fa1787, Unique Entities: 217\n", + "Resource: 8b88687d996f7b9bbcfae4f4ba7c515f55eef34212a0064eb922891d3c99a97e, Unique Entities: 50\n", + "Resource: d632df6f6b49074036d830502a8f22df6b3e75593d9a8cd783d4ccf33d6dd67a, Unique Entities: 272\n", + "Resource: dd14d735a5cc249c6a3c4751e134c2040a83e58aa0c29475faed0825b54c2927, Unique Entities: 48\n", + "Resource: ae9aa5602c72b8a76da0eac063f7190e9211fd198244e244c89d65b41306a192, Unique Entities: 1677\n", + "Resource: 85e3264ae354c8701d3147d13c54a4bc6b5edbefebfe6add3cf010243303ef95, Unique Entities: 84\n" + ] + } + ], + "source": [ + "for idx, rows in result.iterrows():\n", + " collection = rows['collection']\n", + " dataset = rows['dataset']\n", + " resource = rows['resource']\n", + " \n", + " url = f\"http://files.planning.data.gov.uk/{collection}-collection/transformed/{dataset}/{resource}.csv\"\n", + "\n", + " df = pd.read_csv(url)\n", + "\n", + " unique_entities = df['entity'].nunique()\n", + " print(f\"Resource: {resource}, Unique Entities: {unique_entities}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "9d087001", + "metadata": {}, + "source": [ + "---\n", + "## How many more matches do we get using transformed resources over the dataset resource?" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "bdb24080", + "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", + " \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", + "
rowidorganisationnameorganisation_namedatasetcollectionpipelineendpointendpoint_urldocumentation_urllicencelatest_statuslatest_exceptionresourcelatest_log_entry_dateendpoint_entry_dateendpoint_end_dateresource_start_dateresource_end_date
748749government-organisation:D1342Ministry of Housing, Communities & Local Gover...Ministry of Housing, Communities & Local Gover...listed-building-outlinelisted-buildinglisted-building-outline4bd57a7a9d880048f310229d123942a33a338dfd01807f...https://files.planning.data.gov.uk/reporting/l...https://planning.data.gov.ukogl3200c89557a7ac5c73bd83c153912d188848719555e1ddb8d8...2026-03-242026-03-182026-03-19
63236324local-authority:ADUAdur District CouncilAdur District Councilarticle-4-direction-areaarticle-4-directionarticle-4-direction-area0f326a65974b3720aa65c70949a2b4056cfcb79543d706...https://adur-worthing.statmap.co.uk/map/webser...https://www.adur-worthing.gov.uk/planning/arti...ogl32002662361965312f297c799738449d67655fe42a76d10f59...2026-03-232025-11-202025-12-01
63546355local-authority:ADUAdur District CouncilAdur District Councillisted-building-outlinelisted-buildinglisted-building-outline73b1921bcf4e991c9f67e51781a2a2d85b4a65260bd9bf...https://adur-worthing.statmap.co.uk/map/webser...https://www.adur-worthing.gov.uk/planning-poli...ogl32001fdec747f46dd81d17199c02a8272bc1ea36b2ce2515c9...2026-03-242026-01-192026-02-27
64556456local-authority:ASFAshford Borough CouncilAshford Borough Councilarticle-4-direction-areaarticle-4-directionarticle-4-direction-area5f1a05d6c7c32c81657d86e8d6c55e3db9ec0824ea191f...https://www.ashford.gov.uk/media/vlymbjea/arti...https://www.ashford.gov.uk/transparency/open-d...ogl320004804fda473cfa31e82700d842c85a23a19c4b5e984831...2026-03-242025-10-232025-12-31
65116512local-authority:ASFAshford Borough CouncilAshford Borough Councillisted-building-outlinelisted-buildinglisted-building-outline11f92a65f2c5963326433aef82d6f9a66e2f5031bd5f48...https://www.ashford.gov.uk/media/qxgbarwo/list...https://www.ashford.gov.uk/transparency/open-d...ogl32003f3fca9a1e7b2851ff89136f9e97e30368962f4d71b50c...2026-03-242025-09-122025-09-13
\n", + "
" + ], + "text/plain": [ + " rowid organisation \\\n", + "748 749 government-organisation:D1342 \n", + "6323 6324 local-authority:ADU \n", + "6354 6355 local-authority:ADU \n", + "6455 6456 local-authority:ASF \n", + "6511 6512 local-authority:ASF \n", + "\n", + " name \\\n", + "748 Ministry of Housing, Communities & Local Gover... \n", + "6323 Adur District Council \n", + "6354 Adur District Council \n", + "6455 Ashford Borough Council \n", + "6511 Ashford Borough Council \n", + "\n", + " organisation_name \\\n", + "748 Ministry of Housing, Communities & Local Gover... \n", + "6323 Adur District Council \n", + "6354 Adur District Council \n", + "6455 Ashford Borough Council \n", + "6511 Ashford Borough Council \n", + "\n", + " dataset collection pipeline \\\n", + "748 listed-building-outline listed-building listed-building-outline \n", + "6323 article-4-direction-area article-4-direction article-4-direction-area \n", + "6354 listed-building-outline listed-building listed-building-outline \n", + "6455 article-4-direction-area article-4-direction article-4-direction-area \n", + "6511 listed-building-outline listed-building listed-building-outline \n", + "\n", + " endpoint \\\n", + "748 4bd57a7a9d880048f310229d123942a33a338dfd01807f... \n", + "6323 0f326a65974b3720aa65c70949a2b4056cfcb79543d706... \n", + "6354 73b1921bcf4e991c9f67e51781a2a2d85b4a65260bd9bf... \n", + "6455 5f1a05d6c7c32c81657d86e8d6c55e3db9ec0824ea191f... \n", + "6511 11f92a65f2c5963326433aef82d6f9a66e2f5031bd5f48... \n", + "\n", + " endpoint_url \\\n", + "748 https://files.planning.data.gov.uk/reporting/l... \n", + "6323 https://adur-worthing.statmap.co.uk/map/webser... \n", + "6354 https://adur-worthing.statmap.co.uk/map/webser... \n", + "6455 https://www.ashford.gov.uk/media/vlymbjea/arti... \n", + "6511 https://www.ashford.gov.uk/media/qxgbarwo/list... \n", + "\n", + " documentation_url licence latest_status \\\n", + "748 https://planning.data.gov.uk ogl3 200 \n", + "6323 https://www.adur-worthing.gov.uk/planning/arti... ogl3 200 \n", + "6354 https://www.adur-worthing.gov.uk/planning-poli... ogl3 200 \n", + "6455 https://www.ashford.gov.uk/transparency/open-d... ogl3 200 \n", + "6511 https://www.ashford.gov.uk/transparency/open-d... ogl3 200 \n", + "\n", + " latest_exception resource \\\n", + "748 c89557a7ac5c73bd83c153912d188848719555e1ddb8d8... \n", + "6323 2662361965312f297c799738449d67655fe42a76d10f59... \n", + "6354 1fdec747f46dd81d17199c02a8272bc1ea36b2ce2515c9... \n", + "6455 04804fda473cfa31e82700d842c85a23a19c4b5e984831... \n", + "6511 3f3fca9a1e7b2851ff89136f9e97e30368962f4d71b50c... \n", + "\n", + " latest_log_entry_date endpoint_entry_date endpoint_end_date \\\n", + "748 2026-03-24 2026-03-18 \n", + "6323 2026-03-23 2025-11-20 \n", + "6354 2026-03-24 2026-01-19 \n", + "6455 2026-03-24 2025-10-23 \n", + "6511 2026-03-24 2025-09-12 \n", + "\n", + " resource_start_date resource_end_date \n", + "748 2026-03-19 \n", + "6323 2025-12-01 \n", + "6354 2026-02-27 \n", + "6455 2025-12-31 \n", + "6511 2025-09-13 " + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "report_he.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "97712bbd", + "metadata": {}, + "outputs": [], + "source": [ + "transformed = []\n", + "\n", + "for idx, rows in report_he.iterrows():\n", + " organisation = rows['organisation']\n", + " name = rows['name']\n", + " collection = rows['collection']\n", + " dataset = rows['dataset']\n", + " resource = rows['resource']\n", + " \n", + " url = f\"http://files.planning.data.gov.uk/{collection}-collection/transformed/{dataset}/{resource}.csv\"\n", + "\n", + " df = pd.read_csv(url)\n", + "\n", + " unique_entities = df['entity'].nunique()\n", + "\n", + " transformed.append({\n", + " 'organisation': organisation,\n", + " 'name': name,\n", + " 'collection': collection,\n", + " 'dataset': dataset,\n", + " 'resource': resource,\n", + " 'unique_entities': unique_entities\n", + " })\n", + " #print(f\"Resource: {resource}, Unique Entities: {unique_entities}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6f3170e", + "metadata": {}, + "outputs": [], + "source": [ + "# Convert to dataframe\n", + "transformed_resources = pd.DataFrame(transformed)\n", + "\n", + "# Groupby to get entity-count per LPA\n", + "transformed_resources_groupby = transformed_resources.groupby(['dataset', 'name', 'organisation'])['unique_entities'].sum().to_frame('transformed_resources_count').reset_index()#.unstack(fill_value=0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec92775d", + "metadata": {}, + "outputs": [], + "source": [ + "# Merge with platform_entity_count to compare counts\n", + "testing_2 = pd.merge(platform_entity_count, transformed_resources_groupby, on=['dataset', 'name', 'organisation'], how='outer')\n", + "testing_2['match'] = testing_2.apply(lambda row: 'match' if row['platform_count'] == row['transformed_resources_count'] else 'mismatch', axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dc69f2fe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "match\n", + "match 180\n", + "mismatch 104\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing_2['match'].value_counts()\n", + "\n", + "## This is better than the dataset_resource counts, but there are still some mismatches" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "id": "6ab882e2", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datasetnameorganisationplatform_counttransformed_resources_countmatch
1article-4-direction-areaAshford Borough Councillocal-authority:ASF75.056.0mismatch
2article-4-direction-areaBirmingham City Councillocal-authority:BIR13.012.0mismatch
5article-4-direction-areaBuckinghamshire Councillocal-authority:BUC389.0467.0mismatch
8article-4-direction-areaCanterbury City Councillocal-authority:CAT463.0461.0mismatch
9article-4-direction-areaCastle Point Borough Councillocal-authority:CAS4.0NaNmismatch
.....................
273tree-preservation-zoneSouth Staffordshire Councillocal-authority:SST2602.01300.0mismatch
279tree-preservation-zoneTewkesbury Borough Councillocal-authority:TEW556.0445.0mismatch
281tree-preservation-zoneTorbay Councillocal-authority:TOB834.0728.0mismatch
282tree-preservation-zoneWest Berkshire Councillocal-authority:WBK1115.0923.0mismatch
283tree-preservation-zoneWirral Borough Councillocal-authority:WRL2458.01237.0mismatch
\n", + "

104 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "1 article-4-direction-area Ashford Borough Council \n", + "2 article-4-direction-area Birmingham City Council \n", + "5 article-4-direction-area Buckinghamshire Council \n", + "8 article-4-direction-area Canterbury City Council \n", + "9 article-4-direction-area Castle Point Borough Council \n", + ".. ... ... \n", + "273 tree-preservation-zone South Staffordshire Council \n", + "279 tree-preservation-zone Tewkesbury Borough Council \n", + "281 tree-preservation-zone Torbay Council \n", + "282 tree-preservation-zone West Berkshire Council \n", + "283 tree-preservation-zone Wirral Borough Council \n", + "\n", + " organisation platform_count transformed_resources_count \\\n", + "1 local-authority:ASF 75.0 56.0 \n", + "2 local-authority:BIR 13.0 12.0 \n", + "5 local-authority:BUC 389.0 467.0 \n", + "8 local-authority:CAT 463.0 461.0 \n", + "9 local-authority:CAS 4.0 NaN \n", + ".. ... ... ... \n", + "273 local-authority:SST 2602.0 1300.0 \n", + "279 local-authority:TEW 556.0 445.0 \n", + "281 local-authority:TOB 834.0 728.0 \n", + "282 local-authority:WBK 1115.0 923.0 \n", + "283 local-authority:WRL 2458.0 1237.0 \n", + "\n", + " match \n", + "1 mismatch \n", + "2 mismatch \n", + "5 mismatch \n", + "8 mismatch \n", + "9 mismatch \n", + ".. ... \n", + "273 mismatch \n", + "279 mismatch \n", + "281 mismatch \n", + "282 mismatch \n", + "283 mismatch \n", + "\n", + "[104 rows x 6 columns]" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "testing_2.loc[testing_2['match'] == 'mismatch']" + ] + }, + { + "cell_type": "markdown", + "id": "6851d837", + "metadata": {}, + "source": [ + "---\n", + "## Merge all 3 datasets together to compare counts\n", + "The dataset_resource, transformed resource, and the platform data" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "75e25291", + "metadata": {}, + "outputs": [], + "source": [ + "### Merge all three together to compare counts\n", + "final_merge = pd.merge(testing_2, dataset_resource_entity_count, on=['dataset', 'name', 'organisation'], how='outer')" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "id": "8433910d", + "metadata": {}, + "outputs": [], + "source": [ + "final_merge = final_merge.rename(columns={'match': 'platform_vs_transformed_match'})\n", + "\n", + "final_merge['platform_vs_dataset_resource_match'] = final_merge.apply(lambda row: 'match' if row['platform_count'] == row['dataset_resource_count'] else 'mismatch', axis=1)\n", + "final_merge['transformed_vs_dataset_resource_match'] = final_merge.apply(lambda row: 'match' if row['transformed_resources_count'] == row['dataset_resource_count'] else 'mismatch', axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "id": "8bb42cc9", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datasetnameorganisationtransformed_resources_countdataset_resource_counttransformed_vs_dataset_resource_match
0article-4-direction-areaAdur District Councillocal-authority:ADU9.0NaNmismatch
3article-4-direction-areaBristol City Councillocal-authority:BST16.0NaNmismatch
4article-4-direction-areaBroadland District Councillocal-authority:BRO28.0NaNmismatch
5article-4-direction-areaBuckinghamshire Councillocal-authority:BUC467.0256.0mismatch
6article-4-direction-areaCalderdale Metropolitan Borough Councillocal-authority:CLD8.0NaNmismatch
.....................
270tree-preservation-zoneSouth Cambridgeshire District Councillocal-authority:SCA2210.0NaNmismatch
273tree-preservation-zoneSouth Staffordshire Councillocal-authority:SST1300.0NaNmismatch
275tree-preservation-zoneSt Albans City and District Councillocal-authority:SAL544.0NaNmismatch
278tree-preservation-zoneTandridge District Councillocal-authority:TAN885.0NaNmismatch
283tree-preservation-zoneWirral Borough Councillocal-authority:WRL1237.0NaNmismatch
\n", + "

212 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "0 article-4-direction-area Adur District Council \n", + "3 article-4-direction-area Bristol City Council \n", + "4 article-4-direction-area Broadland District Council \n", + "5 article-4-direction-area Buckinghamshire Council \n", + "6 article-4-direction-area Calderdale Metropolitan Borough Council \n", + ".. ... ... \n", + "270 tree-preservation-zone South Cambridgeshire District Council \n", + "273 tree-preservation-zone South Staffordshire Council \n", + "275 tree-preservation-zone St Albans City and District Council \n", + "278 tree-preservation-zone Tandridge District Council \n", + "283 tree-preservation-zone Wirral Borough Council \n", + "\n", + " organisation transformed_resources_count dataset_resource_count \\\n", + "0 local-authority:ADU 9.0 NaN \n", + "3 local-authority:BST 16.0 NaN \n", + "4 local-authority:BRO 28.0 NaN \n", + "5 local-authority:BUC 467.0 256.0 \n", + "6 local-authority:CLD 8.0 NaN \n", + ".. ... ... ... \n", + "270 local-authority:SCA 2210.0 NaN \n", + "273 local-authority:SST 1300.0 NaN \n", + "275 local-authority:SAL 544.0 NaN \n", + "278 local-authority:TAN 885.0 NaN \n", + "283 local-authority:WRL 1237.0 NaN \n", + "\n", + " transformed_vs_dataset_resource_match \n", + "0 mismatch \n", + "3 mismatch \n", + "4 mismatch \n", + "5 mismatch \n", + "6 mismatch \n", + ".. ... \n", + "270 mismatch \n", + "273 mismatch \n", + "275 mismatch \n", + "278 mismatch \n", + "283 mismatch \n", + "\n", + "[212 rows x 6 columns]" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Show mismatches between transformed resources and dataset_resource counts\n", + "trans_dr_mismatch = final_merge.loc[final_merge['transformed_vs_dataset_resource_match'] == 'mismatch'][['dataset', 'name', 'organisation', 'transformed_resources_count', 'dataset_resource_count', 'transformed_vs_dataset_resource_match']]\n", + "trans_dr_mismatch" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "id": "c2c49e91", + "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", + " \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", + " \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", + "
datasetnameorganisationtransformed_resources_countdataset_resource_counttransformed_vs_dataset_resource_match
57article-4-direction-areaNorth Norfolk District Councillocal-authority:NNO42.0NaNmismatch
214treeTandridge District Councillocal-authority:TAN1678.00.0mismatch
178treeGloucester City Councillocal-authority:GLO1358.00.0mismatch
113listed-building-outlineHart District Councillocal-authority:HAT1954.00.0mismatch
97listed-building-outlineCentral Bedfordshire Councillocal-authority:CBF1918.0NaNmismatch
275tree-preservation-zoneSt Albans City and District Councillocal-authority:SAL544.0NaNmismatch
77article-4-direction-areaStoke-on-Trent City Councillocal-authority:STE27.0NaNmismatch
227tree-preservation-zoneCastle Point Borough Councillocal-authority:CAS179.0NaNmismatch
13article-4-direction-areaCotswold District Councillocal-authority:COT22.0NaNmismatch
138listed-building-outlineNorth Tyneside Councillocal-authority:NTY221.00.0mismatch
175treeEast Riding of Yorkshire Councillocal-authority:ERY3476.00.0mismatch
238tree-preservation-zoneGreat Yarmouth Borough Councillocal-authority:GRY314.0NaNmismatch
197treeNorth Somerset Councillocal-authority:NSM4127.00.0mismatch
120listed-building-outlineLondon Borough of Brentlocal-authority:BEN582.00.0mismatch
28article-4-direction-areaGreat Yarmouth Borough Councillocal-authority:GRY18.0NaNmismatch
260tree-preservation-zoneNorth Somerset Councillocal-authority:NSM1484.0NaNmismatch
208treeSouth Gloucestershire Councillocal-authority:SGC5412.00.0mismatch
34article-4-direction-areaHuntingdonshire District Councillocal-authority:HUN6.0NaNmismatch
278tree-preservation-zoneTandridge District Councillocal-authority:TAN885.0NaNmismatch
124listed-building-outlineLondon Borough of Lewishamlocal-authority:LEW364.0NaNmismatch
117listed-building-outlineLiverpool City Councillocal-authority:LIV1538.00.0mismatch
92listed-building-outlineBuckinghamshire Councillocal-authority:BUCNaNNaNmismatch
188treeLondon Borough of Southwarklocal-authority:SWK2503.00.0mismatch
270tree-preservation-zoneSouth Cambridgeshire District Councillocal-authority:SCA2210.0NaNmismatch
190treeLondon Borough of Waltham Forestlocal-authority:WFT2043.00.0mismatch
\n", + "
" + ], + "text/plain": [ + " dataset name \\\n", + "57 article-4-direction-area North Norfolk District Council \n", + "214 tree Tandridge District Council \n", + "178 tree Gloucester City Council \n", + "113 listed-building-outline Hart District Council \n", + "97 listed-building-outline Central Bedfordshire Council \n", + "275 tree-preservation-zone St Albans City and District Council \n", + "77 article-4-direction-area Stoke-on-Trent City Council \n", + "227 tree-preservation-zone Castle Point Borough Council \n", + "13 article-4-direction-area Cotswold District Council \n", + "138 listed-building-outline North Tyneside Council \n", + "175 tree East Riding of Yorkshire Council \n", + "238 tree-preservation-zone Great Yarmouth Borough Council \n", + "197 tree North Somerset Council \n", + "120 listed-building-outline London Borough of Brent \n", + "28 article-4-direction-area Great Yarmouth Borough Council \n", + "260 tree-preservation-zone North Somerset Council \n", + "208 tree South Gloucestershire Council \n", + "34 article-4-direction-area Huntingdonshire District Council \n", + "278 tree-preservation-zone Tandridge District Council \n", + "124 listed-building-outline London Borough of Lewisham \n", + "117 listed-building-outline Liverpool City Council \n", + "92 listed-building-outline Buckinghamshire Council \n", + "188 tree London Borough of Southwark \n", + "270 tree-preservation-zone South Cambridgeshire District Council \n", + "190 tree London Borough of Waltham Forest \n", + "\n", + " organisation transformed_resources_count dataset_resource_count \\\n", + "57 local-authority:NNO 42.0 NaN \n", + "214 local-authority:TAN 1678.0 0.0 \n", + "178 local-authority:GLO 1358.0 0.0 \n", + "113 local-authority:HAT 1954.0 0.0 \n", + "97 local-authority:CBF 1918.0 NaN \n", + "275 local-authority:SAL 544.0 NaN \n", + "77 local-authority:STE 27.0 NaN \n", + "227 local-authority:CAS 179.0 NaN \n", + "13 local-authority:COT 22.0 NaN \n", + "138 local-authority:NTY 221.0 0.0 \n", + "175 local-authority:ERY 3476.0 0.0 \n", + "238 local-authority:GRY 314.0 NaN \n", + "197 local-authority:NSM 4127.0 0.0 \n", + "120 local-authority:BEN 582.0 0.0 \n", + "28 local-authority:GRY 18.0 NaN \n", + "260 local-authority:NSM 1484.0 NaN \n", + "208 local-authority:SGC 5412.0 0.0 \n", + "34 local-authority:HUN 6.0 NaN \n", + "278 local-authority:TAN 885.0 NaN \n", + "124 local-authority:LEW 364.0 NaN \n", + "117 local-authority:LIV 1538.0 0.0 \n", + "92 local-authority:BUC NaN NaN \n", + "188 local-authority:SWK 2503.0 0.0 \n", + "270 local-authority:SCA 2210.0 NaN \n", + "190 local-authority:WFT 2043.0 0.0 \n", + "\n", + " transformed_vs_dataset_resource_match \n", + "57 mismatch \n", + "214 mismatch \n", + "178 mismatch \n", + "113 mismatch \n", + "97 mismatch \n", + "275 mismatch \n", + "77 mismatch \n", + "227 mismatch \n", + "13 mismatch \n", + "138 mismatch \n", + "175 mismatch \n", + "238 mismatch \n", + "197 mismatch \n", + "120 mismatch \n", + "28 mismatch \n", + "260 mismatch \n", + "208 mismatch \n", + "34 mismatch \n", + "278 mismatch \n", + "124 mismatch \n", + "117 mismatch \n", + "92 mismatch \n", + "188 mismatch \n", + "270 mismatch \n", + "190 mismatch " + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trans_dr_mismatch.sample(n=25, random_state=42)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}