Skip to content
Snippets Groups Projects
Commit baf4f0c7 authored by Pieter van der Hijden's avatar Pieter van der Hijden
Browse files

Jupyter Notebook sdg-profiles-statistics updated

parent e7a441c6
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# Generating a report on Aligning a Fab Lab with the UN SDGs # Generating a report on Aligning a Fab Lab with the UN SDGs
#### Author: Pieter van der Hijden (pvdh@sofos.nl) - "Fab Labs and SDGs" Working Group; Pieter van der Hijden (The Netherlands & Suriname) plus global team: Enrico Bassi (Italy), Vaneza Caycho Ñuflo (Peru), Nagwa ElNwishy (Egypt), Neville Govender (South Africa), Ted Hung (Taiwan), Arundhati Jadhav (India), Beno Juarez (Peru), Yogesh Kulkarni (India), Noksy Letsoalo (South Africa), Jean-Baptiste Natali (New Zealand), Wendy Neale (New Zealand), Mess Wright (USA) #### Author: Pieter van der Hijden (pvdh@sofos.nl) - "Fab Labs and SDGs" Working Group; Pieter van der Hijden (The Netherlands & Suriname) plus global team: Enrico Bassi (Italy), Vaneza Caycho Ñuflo (Peru), Nagwa ElNwishy (Egypt), Neville Govender (South Africa), Ted Hung (Taiwan), Arundhati Jadhav (India), Beno Juarez (Peru), Yogesh Kulkarni (India), Noksy Letsoalo (South Africa), Jean-Baptiste Natali (New Zealand), Wendy Neale (New Zealand), Mess Wright (USA)
#### This work is licensed under a Creative Commons Attribution 4.0 International License; https://creativecommons.org/licenses/by/4.0/. #### This work is licensed under a Creative Commons Attribution 4.0 International License; https://creativecommons.org/licenses/by/4.0/.
### Purpose ### Purpose
As a service to the individual fablabs we want to generate a report on a specific fab lab and its alignment with the UN Sustrainable Development Goals (SDGs). The information included is either generic in nature, or derived from various databases (fablabs basic data from fablabs.io, fablabs sdg profiles from sdg profile registration spreadsheet). As a service to the individual fablabs we want to generate a report on a specific fab lab and its alignment with the UN Sustrainable Development Goals (SDGs). The information included is either generic in nature, or derived from various databases (fablabs basic data from fablabs.io, fablabs sdg profiles from sdg profile registration spreadsheet).
### Table of Contents ### Table of Contents
1. Install packages 1. Install packages
1. Import libraries 1. Import libraries
1. Prepare dataframes 1. Prepare dataframes
* Prepare dataframe profiles from gitlab.fabcloud.org * Prepare dataframe profiles from gitlab.fabcloud.org
* Prepare dataframe fablabs from fablabs.io * Prepare dataframe fablabs from fablabs.io
1. Merge profiles with fablabs (left) 1. Merge profiles with fablabs (left)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Install packages ## Install packages
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Install packages # Install packages
!sudo pip3 install pandas !sudo pip3 install pandas
!sudo pip3 install openpyxl !sudo pip3 install openpyxl
``` ```
%% Output %% Output
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (1.2.3) Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (1.2.3)
Requirement already satisfied: numpy>=1.16.5 in /usr/local/lib/python3.7/dist-packages (from pandas) (1.20.1) Requirement already satisfied: numpy>=1.16.5 in /usr/local/lib/python3.7/dist-packages (from pandas) (1.20.1)
Requirement already satisfied: python-dateutil>=2.7.3 in /usr/lib/python3/dist-packages (from pandas) (2.7.3) Requirement already satisfied: python-dateutil>=2.7.3 in /usr/lib/python3/dist-packages (from pandas) (2.7.3)
Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2021.1) Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas) (2021.1)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: openpyxl in /usr/local/lib/python3.7/dist-packages (3.0.7) Requirement already satisfied: openpyxl in /usr/local/lib/python3.7/dist-packages (3.0.7)
Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.7/dist-packages (from openpyxl) (1.0.1) Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.7/dist-packages (from openpyxl) (1.0.1)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Install newest pip (optional) ## Install newest pip (optional)
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
!sudo /usr/bin/python3 -m pip install --upgrade pip !sudo /usr/bin/python3 -m pip install --upgrade pip
``` ```
%% Output %% Output
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: pip in /usr/local/lib/python3.7/dist-packages (21.1.1) Requirement already satisfied: pip in /usr/local/lib/python3.7/dist-packages (21.1.1)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Install libraries ## Install libraries
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
import pandas as pd import pandas as pd
import datetime import datetime
import os import os
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Prepare dataframe 'profiles' from https://gitlab.fabcloud.org ## Prepare dataframe 'profiles' from https://gitlab.fabcloud.org
Options Options
* Read xlsx data from gitlab.fabcloud.org to pandas dataframe 'profiles' * Read xlsx data from gitlab.fabcloud.org to pandas dataframe 'profiles'
* Save dataframe 'profiles' to data/profiles.csv * Save dataframe 'profiles' to data/profiles.csv
* Read dataframe 'profiles' from data/profiles.csv * Read dataframe 'profiles' from data/profiles.csv
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Get data from gitlab.fabcloud.org # Get data from gitlab.fabcloud.org
# Read XLSX sheet with fab lab sdg profiles # Read XLSX sheet with fab lab sdg profiles
url = 'https://gitlab.fabcloud.org/fl-management/fl-sdgs/sdg-workshop/-/raw/master/' url = 'https://gitlab.fabcloud.org/fl-management/fl-sdgs/sdg-workshop/-/raw/master/'
url = url + 'aggregated-results/FabLab-SDGProfile-Registration.xlsx' url = url + 'aggregated-results/FabLab-SDGProfile-Registration.xlsx'
timestamp = datetime.datetime.utcnow() timestamp = datetime.datetime.utcnow()
profiles=pd.read_excel(url, 'processing', index_col=27) profiles=pd.read_excel(url, 'processing', index_col=27)
# Write dataframe to local storage # Write dataframe to local storage
if not os.path.exists('data'): if not os.path.exists('data'):
os.makedirs('data') os.makedirs('data')
# Write dataframe to csv-file # Write dataframe to csv-file
profiles.to_csv('data/profiles.csv') profiles.to_csv('data/profiles.csv')
# Read dataframe from local storage # Read dataframe from local storage
profiles = pd.read_csv('data/profiles.csv') profiles = pd.read_csv('data/profiles.csv')
# log number of objects and number of fields # log number of objects and number of fields
if not os.path.exists('output'): if not os.path.exists('output'):
os.makedirs('output') os.makedirs('output')
line = str(timestamp) + ' - ' + url + ' - ' + str(profiles.shape) line = str(timestamp) + ' - ' + url + ' - ' + str(profiles.shape)
f = open('output/log.txt', 'a') f = open('output/log.txt', 'a')
f.write(line) f.write(line)
#f.close() #f.close()
profiles.shape profiles.shape
``` ```
%% Output %% Output
(244, 29) (244, 29)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Clean dataframe 'profiles' ## Clean dataframe 'profiles'
* Delete verbose and superfluous columns * Delete verbose and superfluous columns
* Skip empty rows * Skip empty rows
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Clean dataframe 'profiles' # Clean dataframe 'profiles'
# Delete verbose and superfluous columns 6-7 # Delete verbose and superfluous columns 6-7
del profiles['Enter your SDG profile by ticking 2-4 SDGs'] del profiles['Enter your SDG profile by ticking 2-4 SDGs']
del profiles['One more thing!'] del profiles['One more thing!']
profiles.info() profiles.info()
``` ```
%% Output %% Output
--------------------------------------------------------------------------- <class 'pandas.core.frame.DataFrame'>
KeyError Traceback (most recent call last) RangeIndex: 244 entries, 0 to 243
/usr/local/lib/python3.7/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance) Data columns (total 27 columns):
3079 try: # Column Non-Null Count Dtype
-> 3080 return self._engine.get_loc(casted_key) --- ------ -------------- -----
3081 except KeyError as err: 0 slug 231 non-null object
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() 1 Tijdstempel 238 non-null object
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() 2 E-mailadres 238 non-null object
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() 3 Your fullname 238 non-null object
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() 4 The name of your fab lab 238 non-null object
KeyError: 'Enter your SDG profile by ticking 2-4 SDGs' 5 Country of your fab lab 237 non-null object
6 URL of your fab lab page on www.fablabs.io 238 non-null object
The above exception was the direct cause of the following exception: 7 SDG 1 9 non-null object
KeyError Traceback (most recent call last) 8 SDG 2 13 non-null object
<ipython-input-38-c721ca6096fb> in <module> 9 SDG 3 26 non-null object
1 # Clean dataframe 'profiles' 10 SDG 4 190 non-null object
2 # Delete verbose and superfluous columns 6-7 11 SDG 5 75 non-null object
----> 3 del profiles['Enter your SDG profile by ticking 2-4 SDGs'] 12 SDG 6 14 non-null object
4 del profiles['One more thing!'] 13 SDG 7 33 non-null object
5 14 SDG 8 68 non-null object
/usr/local/lib/python3.7/dist-packages/pandas/core/generic.py in __delitem__(self, key) 15 SDG 9 156 non-null object
3964 # there was no match, this call should raise the appropriate 16 SDG 10 24 non-null object
3965 # exception: 17 SDG 11 82 non-null object
-> 3966 loc = self.axes[-1].get_loc(key) 18 SDG 12 102 non-null object
3967 self._mgr.idelete(loc) 19 SDG 13 24 non-null object
3968 20 SDG 14 7 non-null object
/usr/local/lib/python3.7/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance) 21 SDG 15 18 non-null object
3080 return self._engine.get_loc(casted_key) 22 SDG 16 2 non-null object
3081 except KeyError as err: 23 SDG 17 42 non-null object
-> 3082 raise KeyError(key) from err 24 summary 244 non-null object
3083 25 status 244 non-null object
3084 if tolerance is not None: 26 check 221 non-null object
KeyError: 'Enter your SDG profile by ticking 2-4 SDGs' dtypes: object(27)
memory usage: 25.8+ KB
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Clean dataframe 'profiles' # Clean dataframe 'profiles'
# Skip empty rows # Skip empty rows
profiles = profiles.loc[profiles['Tijdstempel'].notna()] profiles = profiles.loc[profiles['Tijdstempel'].notna()]
profiles.info() profiles.info()
``` ```
%% Output %% Output
<class 'pandas.core.frame.DataFrame'> <class 'pandas.core.frame.DataFrame'>
Int64Index: 238 entries, 0 to 237 Int64Index: 238 entries, 0 to 237
Data columns (total 27 columns): Data columns (total 27 columns):
# Column Non-Null Count Dtype # Column Non-Null Count Dtype
--- ------ -------------- ----- --- ------ -------------- -----
0 slug 231 non-null object 0 slug 231 non-null object
1 Tijdstempel 238 non-null object 1 Tijdstempel 238 non-null object
2 E-mailadres 238 non-null object 2 E-mailadres 238 non-null object
3 Your fullname 238 non-null object 3 Your fullname 238 non-null object
4 The name of your fab lab 238 non-null object 4 The name of your fab lab 238 non-null object
5 Country of your fab lab 237 non-null object 5 Country of your fab lab 237 non-null object
6 URL of your fab lab page on www.fablabs.io 238 non-null object 6 URL of your fab lab page on www.fablabs.io 238 non-null object
7 SDG 1 9 non-null object 7 SDG 1 9 non-null object
8 SDG 2 13 non-null object 8 SDG 2 13 non-null object
9 SDG 3 26 non-null object 9 SDG 3 26 non-null object
10 SDG 4 190 non-null object 10 SDG 4 190 non-null object
11 SDG 5 75 non-null object 11 SDG 5 75 non-null object
12 SDG 6 14 non-null object 12 SDG 6 14 non-null object
13 SDG 7 33 non-null object 13 SDG 7 33 non-null object
14 SDG 8 68 non-null object 14 SDG 8 68 non-null object
15 SDG 9 156 non-null object 15 SDG 9 156 non-null object
16 SDG 10 24 non-null object 16 SDG 10 24 non-null object
17 SDG 11 82 non-null object 17 SDG 11 82 non-null object
18 SDG 12 102 non-null object 18 SDG 12 102 non-null object
19 SDG 13 24 non-null object 19 SDG 13 24 non-null object
20 SDG 14 7 non-null object 20 SDG 14 7 non-null object
21 SDG 15 18 non-null object 21 SDG 15 18 non-null object
22 SDG 16 2 non-null object 22 SDG 16 2 non-null object
23 SDG 17 42 non-null object 23 SDG 17 42 non-null object
24 summary 238 non-null object 24 summary 238 non-null object
25 status 238 non-null object 25 status 238 non-null object
26 check 221 non-null object 26 check 221 non-null object
dtypes: object(27) dtypes: object(27)
memory usage: 27.0+ KB memory usage: 27.0+ KB
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Prepare dataframe 'fablabs' from https://fablabs.io ## Prepare dataframe 'fablabs' from https://fablabs.io
Options Options
* Read json data from fablabs.io to pandas dataframe 'fablabs' * Read json data from fablabs.io to pandas dataframe 'fablabs'
* Save dataframe 'fablabs' to data/fablabs.csv * Save dataframe 'fablabs' to data/fablabs.csv
* Read dataframe 'fablabs' from data/fablabs.csv * Read dataframe 'fablabs' from data/fablabs.csv
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
# Get data from fablabs.io web site # Get data from fablabs.io web site
# Read JSON from website and convert to Dataframe # Read JSON from website and convert to Dataframe
url = "https://fablabs.io/labs.json?class=btn+btn-primary" url = "https://fablabs.io/labs.json?class=btn+btn-primary"
timestamp = datetime.datetime.utcnow() timestamp = datetime.datetime.utcnow()
fablabs = pd.read_json(url) fablabs = pd.read_json(url)
fablabs = fablabs.set_index('slug') fablabs = fablabs.set_index('slug')
# Write dataframe to local storage # Write dataframe to local storage
if not os.path.exists('data'): if not os.path.exists('data'):
os.makedirs('data') os.makedirs('data')
# Write dataframe to csv-file # Write dataframe to csv-file
fablabs.to_csv('data/fablabs.csv') fablabs.to_csv('data/fablabs.csv')
# Read dataframe from local storage # Read dataframe from local storage
#fablabs = pd.read_csv('data/fablabs.csv') #fablabs = pd.read_csv('data/fablabs.csv')
# log number of objects and number of fields # log number of objects and number of fields
if not os.path.exists('output'): if not os.path.exists('output'):
os.makedirs('output') os.makedirs('output')
line = str(timestamp) + ' - ' + url + ' - ' + str(fablabs.shape) line = str(timestamp) + ' - ' + url + ' - ' + str(fablabs.shape)
f = open('output/log.txt', 'a') f = open('output/log.txt', 'a')
f.write(line) f.write(line)
#f.close() #f.close()
fablabs.info() fablabs.info()
``` ```
%% Output %% Output
92 <class 'pandas.core.frame.DataFrame'>
Index: 2015 entries, ping to ZapLab
Data columns (total 22 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 2015 non-null int64
1 name 2015 non-null object
2 kind_name 2015 non-null object
3 parent_id 687 non-null float64
4 blurb 1968 non-null object
5 description 1986 non-null object
6 avatar_url 1655 non-null object
7 header_url 1322 non-null object
8 address_1 1987 non-null object
9 address_2 1985 non-null object
10 city 2015 non-null object
11 county 2015 non-null object
12 postal_code 2013 non-null object
13 country_code 2015 non-null object
14 latitude 1838 non-null float64
15 longitude 1838 non-null float64
16 address_notes 1986 non-null object
17 phone 1986 non-null object
18 email 1986 non-null object
19 capabilities 2015 non-null object
20 activity_status 1431 non-null object
21 links 2015 non-null object
dtypes: float64(3), int64(1), object(18)
memory usage: 212.5+ KB
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Merge profiles data with fablabs data ## Merge profiles data with fablabs data
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
#air_quality = pd.merge(air_quality, stations_coord, how="left", on="location")
profiles = pd.merge(profiles, fablabs, how="left", on="slug") profiles = pd.merge(profiles, fablabs, how="left", on="slug")
profiles.info() profiles.info()
``` ```
%% Output %% Output
<class 'pandas.core.frame.DataFrame'> <class 'pandas.core.frame.DataFrame'>
Int64Index: 238 entries, 0 to 237 Int64Index: 238 entries, 0 to 237
Data columns (total 49 columns): Data columns (total 49 columns):
# Column Non-Null Count Dtype # Column Non-Null Count Dtype
--- ------ -------------- ----- --- ------ -------------- -----
0 slug 231 non-null object 0 slug 231 non-null object
1 Tijdstempel 238 non-null object 1 Tijdstempel 238 non-null object
2 E-mailadres 238 non-null object 2 E-mailadres 238 non-null object
3 Your fullname 238 non-null object 3 Your fullname 238 non-null object
4 The name of your fab lab 238 non-null object 4 The name of your fab lab 238 non-null object
5 Country of your fab lab 237 non-null object 5 Country of your fab lab 237 non-null object
6 URL of your fab lab page on www.fablabs.io 238 non-null object 6 URL of your fab lab page on www.fablabs.io 238 non-null object
7 SDG 1 9 non-null object 7 SDG 1 9 non-null object
8 SDG 2 13 non-null object 8 SDG 2 13 non-null object
9 SDG 3 26 non-null object 9 SDG 3 26 non-null object
10 SDG 4 190 non-null object 10 SDG 4 190 non-null object
11 SDG 5 75 non-null object 11 SDG 5 75 non-null object
12 SDG 6 14 non-null object 12 SDG 6 14 non-null object
13 SDG 7 33 non-null object 13 SDG 7 33 non-null object
14 SDG 8 68 non-null object 14 SDG 8 68 non-null object
15 SDG 9 156 non-null object 15 SDG 9 156 non-null object
16 SDG 10 24 non-null object 16 SDG 10 24 non-null object
17 SDG 11 82 non-null object 17 SDG 11 82 non-null object
18 SDG 12 102 non-null object 18 SDG 12 102 non-null object
19 SDG 13 24 non-null object 19 SDG 13 24 non-null object
20 SDG 14 7 non-null object 20 SDG 14 7 non-null object
21 SDG 15 18 non-null object 21 SDG 15 18 non-null object
22 SDG 16 2 non-null object 22 SDG 16 2 non-null object
23 SDG 17 42 non-null object 23 SDG 17 42 non-null object
24 summary 238 non-null object 24 summary 238 non-null object
25 status 238 non-null object 25 status 238 non-null object
26 check 221 non-null object 26 check 221 non-null object
27 id 225 non-null float64 27 id 225 non-null float64
28 name 225 non-null object 28 name 225 non-null object
29 kind_name 225 non-null object 29 kind_name 225 non-null object
30 parent_id 75 non-null float64 30 parent_id 75 non-null float64
31 blurb 224 non-null object 31 blurb 224 non-null object
32 description 224 non-null object 32 description 224 non-null object
33 avatar_url 193 non-null object 33 avatar_url 193 non-null object
34 header_url 171 non-null object 34 header_url 171 non-null object
35 address_1 224 non-null object 35 address_1 224 non-null object
36 address_2 224 non-null object 36 address_2 224 non-null object
37 city 225 non-null object 37 city 225 non-null object
38 county 225 non-null object 38 county 225 non-null object
39 postal_code 225 non-null object 39 postal_code 225 non-null object
40 country_code 225 non-null object 40 country_code 225 non-null object
41 latitude 217 non-null float64 41 latitude 217 non-null float64
42 longitude 217 non-null float64 42 longitude 217 non-null float64
43 address_notes 224 non-null object 43 address_notes 224 non-null object
44 phone 224 non-null object 44 phone 224 non-null object
45 email 224 non-null object 45 email 224 non-null object
46 capabilities 225 non-null object 46 capabilities 225 non-null object
47 activity_status 206 non-null object 47 activity_status 206 non-null object
48 links 225 non-null object 48 links 225 non-null object
dtypes: float64(4), object(45) dtypes: float64(4), object(45)
memory usage: 51.1+ KB memory usage: 51.1+ KB
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## State-of-affairs ## State-of-affairs
* input profiles, input fablabs and merging profiles+fablabs ok * input profiles, input fablabs and merging profiles+fablabs ok
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment