Back to Blog

Data Model

Data model for Zürich datasets

The Zürich Statistical Office collects data on the city and its residents. This data is published as Linked Data.

In this tutorial, we will explain the linked data model behind it. Mainly, we will guide you through the data structure. The tutorial will show you available datasets, and the shape they take. We will look into queries explaining the data structure as well as available dimensions.

SPARQL endpoint

Data by the Zürich Statistical Office is published as Linked Data. It can be accessed with SPARQL queries. You can send queries using HTTP requests. The API endpoint is https://ld.integ.stadt-zuerich.ch/query.

We use the SPARQL kernel in a jupyter notebook to communicate with the database (you may need to configure this via menu Kernel -> Change kernel -> SPARQL). First, let's configure the endpoint.

In [1]:
#Params
%endpoint https://ld.integ.stadt-zuerich.ch/query
%auth basic public public
%display table

%show 50
Endpoint set to: https://ld.integ.stadt-zuerich.ch/query
HTTP authentication: method=basic, user=public, passwd set
Display: table
Result maximum size: 50

Graphs

One endpoint can contain multiple named graphs.

You can see what graphs are available using WHERE and GRAPH statements.

These graphs have potentilly nothing in common, they are simply stored in the same database.

Here, we have one endpoint storing information on subject as diverse as the train timetable, electricity prices, or animal diseases:

All those graphs can be accessed from the same SPARQL endpoint.

Graph by Zürich Statistical Office

Datasets from the Zürich Statistical Office are published in the following named graph: <https://lindas.admin.ch/stadtzuerich/stat>

You can limit your queries to one named graph using WHERE and FROM statements.

In [3]:
# List random triples in the graph

SELECT *
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {?s ?p ?o}
LIMIT 10
OFFSET 100

Data cubes

Datasets published by Zürich Statistial Office are stored as data cubes. Let's check the cube definition in its documentation:

Cube
Represents the entry point for a collection of observations, conforming to some common dimensional structure.

We can find all data cubes by defining <https://cube.link/Cube> as object.

In [4]:
# List all data cubes

SELECT ?cubes
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?cubes a <https://cube.link/Cube> .
}
cubes
https://ld.stadt-zuerich.ch/statistics/WHG
https://ld.stadt-zuerich.ch/statistics/WHA-ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM
https://ld.stadt-zuerich.ch/statistics/WHA
https://ld.stadt-zuerich.ch/statistics/ZIM-WHA
https://ld.stadt-zuerich.ch/statistics/APZ
https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM
https://ld.stadt-zuerich.ch/statistics/BEW
https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-HEL
https://ld.stadt-zuerich.ch/statistics/ANT-GGH-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT
https://ld.stadt-zuerich.ch/statistics/BEW-SEX
https://ld.stadt-zuerich.ch/statistics/WHG-ZIM
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/GES-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/AST-BTA
https://ld.stadt-zuerich.ch/statistics/TIA-BTA
https://ld.stadt-zuerich.ch/statistics/WRT-BTA-EAP
https://ld.stadt-zuerich.ch/statistics/TII-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/TIA-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/TII-BTA
https://ld.stadt-zuerich.ch/statistics/AST-BEW-BTA
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/GES-SEX
https://ld.stadt-zuerich.ch/statistics/BES-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA
https://ld.stadt-zuerich.ch/statistics/BES-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-ZSA
Total: 34, Shown: 34

All cubes have the same data structure. This means we can write very similar queries to get data from different cubes.

Data cubes have the following properties:

In [5]:
# Cube properties

SELECT DISTINCT ?properties
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?s a <https://cube.link/Cube> ;
    ?properties ?o.
}

Let's learn more about available data cubes. We can access cube description using <http://schema.org/name> property. We will also get its id using <http://schema.org/identifier>. By defining schema and cube as PREFIX, we can save some typing.

In [6]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT *
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?cube a cube:Cube ;
       schema:name ?description ;
       schema:identifier ?id .
}
cube description id
https://ld.stadt-zuerich.ch/statistics/WHG Statistische Wohnungen WHG
https://ld.stadt-zuerich.ch/statistics/WHG Statistische Wohnungen nach Zeit WHG
https://ld.stadt-zuerich.ch/statistics/WHA-ZIM Wohnungen (ohne Appartements) nach Zeit, Zimmerzahl einer Wohnung WHA-ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM Zimmer ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM Zimmer nach Zeit ZIM
https://ld.stadt-zuerich.ch/statistics/WHA Wohnungen (ohne Appartements) WHA
https://ld.stadt-zuerich.ch/statistics/WHA Wohnungen (ohne Appartements) nach Zeit WHA
https://ld.stadt-zuerich.ch/statistics/ZIM-WHA Zimmer nach Zeit, Wohnungsart ZIM-WHA
https://ld.stadt-zuerich.ch/statistics/APZ Appartementzimmer APZ
https://ld.stadt-zuerich.ch/statistics/APZ Appartementzimmer nach Zeit APZ
https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM Quadratmeterpreis nach Eigentümerart, Handänderungsart, Objektart, Zeit, Zimmerzahl einer Wohnung QMP-EIG-HAA-OBJ-ZIM
https://ld.stadt-zuerich.ch/statistics/BEW Wirtschaftliche Wohnbevölkerung BEW
https://ld.stadt-zuerich.ch/statistics/BEW Wirtschaftliche Wohnbevölkerung nach Zeit BEW
https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX Wirtschaftliche Wohnbevölkerung nach Heimatland, Geschlecht, Zeit BEW-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-HEL Wirtschaftliche Wohnbevölkerung nach Heimatland, Zeit BEW-HEL
https://ld.stadt-zuerich.ch/statistics/ANT-GGH-HEL Anteil nach Grundgesamtheit, Heimatland, Zeit ANT-GGH-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT Wirtschaftliche Wohnbevölkerung nach Alter, Zeit BEW-ALT
https://ld.stadt-zuerich.ch/statistics/BEW-SEX Wirtschaftliche Wohnbevölkerung nach Geschlecht, Zeit BEW-SEX
https://ld.stadt-zuerich.ch/statistics/WHG-ZIM Statistische Wohnungen nach Zeit, Zimmerzahl einer Wohnung WHG-ZIM
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX-TOU Sterbefälle (wirtschaftlich) nach Alter, Geschlecht, Zeit, Todesursachen GES-ALT-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/GES-SEX-TOU Sterbefälle (wirtschaftlich) nach Geschlecht, Zeit, Todesursachen GES-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/AST-BTA Arbeitsstätten nach Betriebsart, Zeit AST-BTA
https://ld.stadt-zuerich.ch/statistics/TIA-BTA Tierarten nach Betriebsart, Zeit TIA-BTA
https://ld.stadt-zuerich.ch/statistics/WRT-BTA-EAP Wert nach Betriebsart, Erfolgsrechnung, Zeit WRT-BTA-EAP
https://ld.stadt-zuerich.ch/statistics/TII-BTA-TIG Tierindividuen nach Betriebsart, Tiergattung, Zeit TII-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/TIA-BTA-TIG Tierarten nach Betriebsart, Tiergattung, Zeit TIA-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/TII-BTA Tierindividuen nach Betriebsart, Zeit TII-BTA
https://ld.stadt-zuerich.ch/statistics/AST-BEW-BTA Arbeitsstätten nach Bewilligung, Betriebsart, Zeit AST-BEW-BTA
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX Sterbefälle (wirtschaftlich) nach Alter, Geschlecht, Zeit GES-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/GES-SEX Sterbefälle (wirtschaftlich) nach Geschlecht, Zeit GES-SEX
https://ld.stadt-zuerich.ch/statistics/BES-BTA-SEX Beschäftigte nach Betriebsart, Geschlecht, Zeit BES-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA Zuschauer/innen, Besucher/innen nach Betriebsart, Zeit ZUS-BTA
https://ld.stadt-zuerich.ch/statistics/BES-BTA Beschäftigte nach Betriebsart, Zeit BES-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-HEL Zuschauer/innen, Besucher/innen nach Betriebsart, Heimatland, Zeit ZUS-BTA-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL-SEX Wirtschaftliche Wohnbevölkerung nach Alter, Heimatland, Geschlecht, Zeit BEW-ALT-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL Wirtschaftliche Wohnbevölkerung nach Alter, Heimatland, Zeit BEW-ALT-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-SEX Wirtschaftliche Wohnbevölkerung nach Alter, Geschlecht, Zeit BEW-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-SEX Zuschauer/innen, Besucher/innen nach Betriebsart, Geschlecht, Zeit ZUS-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-ZSA Zuschauer/innen, Besucher/innen nach Betriebsart, Zeit, Zuschauer- bzw. Besucherart ZUS-BTA-ZSA
Total: 39, Shown: 39

You can see that some cubes have more than one description.

Observation set

Observations in data cubes are stored in observation set (<https://cube.link/observationSet>). Let's check the observationSet definition in its documentation:

observationSet
Connects a cube with a set of observations.

We can find all observations in a cube using cube:observationSet/cube:observation as predicate. Let's query all observations in <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> cube.

We can count the number of observations using COUNT statement

In [8]:
# Count observations in a data cube

PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT (COUNT(?obs) AS ?count)
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
           cube:observationSet/cube:observation ?obs.
    # Equivalent to:
    #       cube:observationSet ?observationSet.
    #?observationSet cube:observation ?obs.
}
count
9512
Total: 1, Shown: 1

So in BEW-HEL-SEX cube we have almost 10k observations about the population of Zürich!

Observations

Let's take a closer look at the observations. We can get all observation properties using this query:

In [9]:
# Observation properties

PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT DISTINCT ?obsProperty
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?dataset a cube:Cube;
             cube:observationSet/cube:observation ?observation. 
    ?observation ?obsProperty ?obsVal.
}
obsProperty
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
https://ld.stadt-zuerich.ch/statistics/property/ZEIT
http://schema.org/identifier
https://ld.stadt-zuerich.ch/statistics/property/TIME
https://ld.stadt-zuerich.ch/statistics/property/RAUM
https://ld.stadt-zuerich.ch/statistics/measure/WHG
https://ld.stadt-zuerich.ch/statistics/attribute/KORREKTUR
https://cube.link/observedBy
https://ld.stadt-zuerich.ch/statistics/property/ZIM
https://ld.stadt-zuerich.ch/statistics/measure/WHA
https://ld.stadt-zuerich.ch/statistics/measure/ZIM
https://ld.stadt-zuerich.ch/statistics/property/WHA
https://ld.stadt-zuerich.ch/statistics/measure/APZ
https://ld.stadt-zuerich.ch/statistics/property/EIG
https://ld.stadt-zuerich.ch/statistics/property/HAA
https://ld.stadt-zuerich.ch/statistics/property/OBJ
https://ld.stadt-zuerich.ch/statistics/measure/QMP
https://ld.stadt-zuerich.ch/statistics/measure/BEW
https://ld.stadt-zuerich.ch/statistics/property/HEL
https://ld.stadt-zuerich.ch/statistics/property/SEX
https://ld.stadt-zuerich.ch/statistics/property/GGH
https://ld.stadt-zuerich.ch/statistics/measure/ANT
https://ld.stadt-zuerich.ch/statistics/property/ALT
https://ld.stadt-zuerich.ch/statistics/property/TOU
https://ld.stadt-zuerich.ch/statistics/measure/GES
https://ld.stadt-zuerich.ch/statistics/property/BTA
https://ld.stadt-zuerich.ch/statistics/measure/AST
https://ld.stadt-zuerich.ch/statistics/measure/TIA
https://ld.stadt-zuerich.ch/statistics/property/EAP
https://ld.stadt-zuerich.ch/statistics/measure/WRT
https://ld.stadt-zuerich.ch/statistics/property/TIG
https://ld.stadt-zuerich.ch/statistics/measure/TII
https://ld.stadt-zuerich.ch/statistics/property/BEW
https://ld.stadt-zuerich.ch/statistics/measure/BES
https://ld.stadt-zuerich.ch/statistics/measure/ZUS
https://ld.stadt-zuerich.ch/statistics/property/ZSA
Total: 36, Shown: 36

Quite a bit! Now, not every dataset will have all those properties.

Let's get a list of properties for the <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> data cube. We will also get its labels using schema:name, and descrption using schema:description.

Since not all properties have a description, we will use the OPTIONAL statement to query it.

In [10]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT DISTINCT ?obsProperty ?label ?description 
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?observation. 
    ?observation ?obsProperty ?obsVal.
    ?obsProperty schema:name ?label .
    OPTIONAL {
        ?obsProperty schema:description ?description .
    }
}
obsProperty label description
https://ld.stadt-zuerich.ch/statistics/property/ZEIT Zeit Repräsentation der Zeit als Konzept, repräsentiert die vollständige Komplexität.
https://ld.stadt-zuerich.ch/statistics/property/TIME Zeit Repräsentation der Zeit als ISO 8601 Datum (vereinfacht).
https://ld.stadt-zuerich.ch/statistics/property/RAUM Raum
https://ld.stadt-zuerich.ch/statistics/property/HEL Heimatland
https://ld.stadt-zuerich.ch/statistics/property/SEX Geschlecht
https://ld.stadt-zuerich.ch/statistics/measure/BEW Wirtschaftliche Wohnbevölkerung Wirtschaftliche Wohnbevölkerung
Total: 6, Shown: 6

We can see that BEW-HEL-SEX data cube contains data on the population across:

  • time (german: Zeit)
  • place (german: Raum)
  • gender (german: Geschlecht)
  • origin (german: Heimatland)

Knowing properties, we can directlty query the measurements. Now, we are able to find the actual data: number of inhabitants across time, place, gender, and origin.

We will find the measurements using <https://ld.stadt-zuerich.ch/statistics/measure/BEW> as the observation's property. We will also the cube's dimensions using:

  • <https://ld.stadt-zuerich.ch/statistics/property/RAUM> for place
  • <https://ld.stadt-zuerich.ch/statistics/property/TIME> for time
  • <https://ld.stadt-zuerich.ch/statistics/property/HEL> for origin
  • <https://ld.stadt-zuerich.ch/statistics/property/SEX> for gender

And again, making use of PREFIX makes the query more readable.

In [11]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?origin ?gender ?count
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:RAUM ?place ;
                 property:TIME ?time ;
                 property:HEL ?origin ;
                 property:SEX ?gender .
    
}
LIMIT 10
time place origin gender count
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00013 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 327.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00031 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0001 3227.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00044 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 2280.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00061 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0001 7723.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00074 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0001 3469.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00082 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 1077.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00102 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0001 2531.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00122 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 2181.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00119 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 7926.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00102 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 2210.0
Total: 10, Shown: 10

To make the output more readable, let's replace the IRIs with the corresponding labels. This can be achieved by using schema:name for each property.

In [12]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?origin ?gender ?count
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:RAUM/schema:name ?place ;
                 property:TIME  ?time ;
                 property:HEL/schema:name  ?origin ;
                 property:SEX/schema:name  ?gender .
    
}
LIMIT 10
time place origin gender count
1952-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 28641.0
1938-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 13742.0
1947-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 20036.0
1950-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 24627.0
1968-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 39727.0
1937-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 13531.0
1934-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 12761.0
1945-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 17381.0
1955-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 34351.0
1963-12-31 alter Kreis 11 (1934-1969) Schweiz weiblich 39948.0
Total: 10, Shown: 10

Volià! We now got all measurements across all dimensions in the BEW-ALT-SEX data cube. The data could be further refined, for example by filtering on gender or place.

Let's do the same exercise for the QMP-EIG-HAA-OBJ-ZIM data cube.

First, let's get observations' properties.

In [13]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT DISTINCT ?obsProperty ?label ?description 
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM> a cube:Cube;
             cube:observationSet/cube:observation ?observation. 
    ?observation ?obsProperty ?obsVal.
    ?obsProperty schema:name ?label .
    OPTIONAL {
        ?obsProperty schema:description ?description .
    }
}
obsProperty label description
https://ld.stadt-zuerich.ch/statistics/property/ZEIT Zeit Repräsentation der Zeit als Konzept, repräsentiert die vollständige Komplexität.
https://ld.stadt-zuerich.ch/statistics/property/TIME Zeit Repräsentation der Zeit als ISO 8601 Datum (vereinfacht).
https://ld.stadt-zuerich.ch/statistics/property/RAUM Raum
https://ld.stadt-zuerich.ch/statistics/property/EIG Eigentümerart
https://ld.stadt-zuerich.ch/statistics/property/HAA Handänderungsart
https://ld.stadt-zuerich.ch/statistics/property/OBJ Objektart
https://ld.stadt-zuerich.ch/statistics/property/ZIM Zimmerzahl einer Wohnung
https://ld.stadt-zuerich.ch/statistics/measure/QMP Quadratmeterpreis Preis in Franken pro Quadratmeter
Total: 8, Shown: 8

Now, let's use these properties to query the data.

In [14]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?rooms ?ownership ?haa ?type ?price
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM> a cube:Cube;
             cube:observationSet/cube:observation ?obs . 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/QMP> ?price ;
                 property:TIME  ?time ;
                 property:RAUM/schema:name ?place ;
                 property:ZIM/schema:name  ?rooms ;
                 property:EIG/schema:name  ?ownership ;
                 property:HAA/schema:name  ?market ;
                 property:OBJ/schema:name  ?type .
    
}
LIMIT 10
time place rooms ownership haa type price
2011-12-31 Sihlfeld 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2017-12-31 Kreis 3 (ab 1915) 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 12723.0
2014-12-31 Fluntern 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2011-12-31 Altstetten 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 6323.0
2014-12-31 City 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2012-12-31 Sihlfeld 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2015-12-31 Mühlebach 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 11041.0
2015-12-31 Altstetten 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2009-12-31 Hochschulen 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2011-12-31 Witikon 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 8352.0
Total: 10, Shown: 10

You can see that some prices come back as zero. Getting an appartment for free is extremely rare in Switzerland. That's presumably a data issue.

Let's remove those invalid observations using a FILTER statement.

In [15]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?rooms ?ownership ?haa ?type ?price
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM> a cube:Cube;
             cube:observationSet/cube:observation ?obs . 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/QMP> ?price ;
                 property:TIME  ?time ;
                 property:RAUM/schema:name ?place ;
                 property:ZIM/schema:name  ?rooms ;
                 property:EIG/schema:name  ?ownership ;
                 property:HAA/schema:name  ?market ;
                 property:OBJ/schema:name  ?type .
    FILTER (?price > 0)  
}
LIMIT 10
time place rooms ownership haa type price
2011-12-31 Escher Wyss 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 12068.0
2010-12-31 Unterstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 8560.0
2011-12-31 Oberstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 11695.0
2017-12-31 Oberstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 17348.0
2014-12-31 Unterstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 9973.0
2011-12-31 Unterstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 12166.0
2017-12-31 Alt-Wiedikon 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 9154.0
2016-12-31 Oberstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 13824.0
2015-12-31 Unterstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 10389.0
2009-12-31 Oberstrass 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 15457.0
Total: 10, Shown: 10

That's better!

Data slices

Thus far, we queried all observations from the data cube. Sometimes, you are interested in just some of the dimensions. You can aggregate the results using GROUP BY and SUM statements.

Let's find the total number of people in Zurich accross property:TIME. To do this, we sum the remaining dimensions:

  • property:RAUM
  • property:HEL
  • property:SEX

This can be achieved by leaving them out of the GROUP BY statement. All unmentioned variables will be aggregated.

In [16]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time (SUM(?count) AS ?aggCount)
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:TIME  ?time .
    
}
GROUP BY ?time
LIMIT 10
time aggCount
1920-12-31 206273.0
1921-12-31 200873.0
1922-12-31 199567.0
1923-12-31 202949.0
1924-12-31 205202.0
1925-12-31 207399.0
1926-12-31 212571.0
1927-12-31 217734.0
1928-12-31 227081.0
1929-12-31 236267.0
Total: 10, Shown: 10

You can also filter the results to include only one dimension. This can be done by setting the object to the value you are interested in.

Let's get the number of female inhabitants over time. First, we will find IRIs for gender.

In [17]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT DISTINCT ?genderIRI ?gender
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs property:SEX ?genderIRI.
    ?obs property:SEX/schema:name ?gender .
    
}

<https://ld.stadt-zuerich.ch/statistics/code/SEX0002> stands for female (german weiblich). We will use it to filter observations for female only.

In SPARQL, this can be done by setting observation predicate to property:SEX, and its object to <https://ld.stadt-zuerich.ch/statistics/code/SEX0002>.

In [18]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?origin ?count
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:RAUM/schema:name ?place ;
                 property:TIME  ?time ;
                 property:HEL/schema:name  ?origin ;
                 property:SEX  <https://ld.stadt-zuerich.ch/statistics/code/SEX0002> .
    
} 
LIMIT 10
time place origin count
2008-12-31 Altstetten Schweiz 9740.0
1963-12-31 Kreis 9 (ab 1934) Schweiz 20817.0
1990-12-31 Altstetten Schweiz 11162.0
2011-12-31 Altstetten Schweiz 10359.0
2007-12-31 Altstetten Schweiz 9671.0
2017-12-31 Altstetten Schweiz 10658.0
2009-12-31 Altstetten Schweiz 9898.0
2011-12-31 Kreis 9 (ab 1934) Schweiz 17819.0
1984-12-31 Altstetten Schweiz 11771.0
1981-12-31 Kreis 9 (ab 1934) Schweiz NaN
Total: 10, Shown: 10

Volià, the number of female inhabitants across time, origin, and city district.

SPEX

There are many ways to learn about the structure of linked data. SPARQL queries may seem dense at first and may take some time to get you to the right place. However, as you get better with SPARQL, they are a great tool to slice data.

Another way to discover linked data is SPEX, a web based tool that visualizes the structure of a linked data source.

SPEX