Checking The Met database textiles entries

Import Met CSV database into a dataframe

This is more than 400,000 rows, so it may take 10-20 seconds or more

%%time
import csv
from urllib.request import urlopen
import codecs
# from tqdm import tqdm
# from tqdm._tqdm_notebook import tqdm_notebook
import requests
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from dateutil.parser import parse

# The Met's weekly CSV dump URL in Github is quite big at 250 Mbytes
# Comment out for now, since this is slow to load. 
# url = 'https://media.githubusercontent.com/media/metmuseum/openaccess/master/MetObjects.csv'

# Use local copy of CSV file for speed and read the CSV file into a pandas dataframe
url = 'metmuseum/MetObjects-20190425.csv'
met_df = pd.read_csv(url,low_memory=False)
CPU times: user 8.37 s, sys: 944 ms, total: 9.31 s
Wall time: 9.04 s

Examine the structure of rows

Take a look at some of the rows. NaN means "not a number" or a blank from the CSV file.

met_df.sample(5)
Object Number Is Highlight Is Public Domain Object ID Department Object Name Title Culture Period Dynasty ... Locale Locus Excavation River Classification Rights and Reproduction Link Resource Metadata Date Repository Tags
378326 2013.173.4 False True 623029 Photographs Photograph Figure 8: Contraction of the right m. frontalis. NaN NaN NaN ... NaN NaN NaN NaN Photographs NaN http://www.metmuseum.org/art/collection/search... 4/22/2019 8:00:03 AM Metropolitan Museum of Art, New York, NY Hands|Men|Portraits
222802 1982.1078 False False 350250 Drawings and Prints Book Breath. Inspired by seven poems by Stéphane Ma... NaN NaN NaN ... NaN NaN NaN NaN Books NaN http://www.metmuseum.org/art/collection/search... 4/22/2019 8:00:03 AM Metropolitan Museum of Art, New York, NY NaN
135544 47.28.2 False True 227252 European Sculpture and Decorative Arts Piece Piece French NaN NaN ... NaN NaN NaN NaN Textiles-Velvets NaN http://www.metmuseum.org/art/collection/search... 4/22/2019 8:00:03 AM Metropolitan Museum of Art, New York, NY Flowers|Leaves
2751 45.100.95 False True 2952 American Decorative Arts Cup plate Cup plate American NaN NaN ... NaN NaN NaN NaN Glass NaN http://www.metmuseum.org/art/collection/search... 4/22/2019 8:00:03 AM Metropolitan Museum of Art, New York, NY Dishes
134196 36.90.2501 False False 225572 European Sculpture and Decorative Arts Ribbon Ribbon French NaN NaN ... NaN NaN NaN NaN Textiles-Trimmings NaN http://www.metmuseum.org/art/collection/search... 4/22/2019 8:00:03 AM Metropolitan Museum of Art, New York, NY Samples

5 rows × 44 columns

Statistics on most used and unique terms

The most frequently used terms can be found in the row labeled "top." In summary:

  1. Drawings and prints departement has the most items
  2. Object number "62.635" is used four times, which we can investigate below.
met_df.describe(include=[np.object])
Object Number Department Object Name Title Culture Period Dynasty Reign Portfolio Artist Role ... Locale Locus Excavation River Classification Rights and Reproduction Link Resource Metadata Date Repository Tags
count 494311 494311 489851 463050 209050 89550 23284 11205 22217 285440 ... 15562 7329 15967 2098 437900 24940 494311 494311 494311 277566
unique 491608 19 28302 251441 7267 1811 381 380 3274 6326 ... 859 1352 364 230 1227 1427 494311 1 1 55172
top 62.635 Drawings and Prints Print Fragment American Edo period (1615–1868) Dynasty 18 reign of Amenhotep III Les Images De Tous Les Saincts et Saintes de L... Artist ... Cemetery debris MMA excavations Upper Sepik River Prints © Walker Evans Archive, The Metropolitan Museu... http://www.metmuseum.org/art/collection/search... 4/22/2019 8:00:03 AM Metropolitan Museum of Art, New York, NY Men|Portraits|Baseball|Athletes
freq 4 178182 101945 7011 28404 8879 7178 2730 601 115028 ... 1925 416 2387 361 76967 9204 1 494311 494311 9706

4 rows × 39 columns

met_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 494311 entries, 0 to 494310
Data columns (total 44 columns):
Object Number              494311 non-null object
Is Highlight               494311 non-null bool
Is Public Domain           494311 non-null bool
Object ID                  494311 non-null int64
Department                 494311 non-null object
Object Name                489851 non-null object
Title                      463050 non-null object
Culture                    209050 non-null object
Period                     89550 non-null object
Dynasty                    23284 non-null object
Reign                      11205 non-null object
Portfolio                  22217 non-null object
Artist Role                285440 non-null object
Artist Prefix              98323 non-null object
Artist Display Name        287530 non-null object
Artist Display Bio         237989 non-null object
Artist Suffix              12208 non-null object
Artist Alpha Sort          287495 non-null object
Artist Nationality         193440 non-null object
Artist Begin Date          240617 non-null object
Artist End Date            237808 non-null object
Object Date                479252 non-null object
Object Begin Date          494311 non-null int64
Object End Date            494311 non-null int64
Medium                     486728 non-null object
Dimensions                 417876 non-null object
Credit Line                493520 non-null object
Geography Type             60369 non-null object
City                       32248 non-null object
State                      2805 non-null object
County                     8576 non-null object
Country                    76812 non-null object
Region                     31975 non-null object
Subregion                  22277 non-null object
Locale                     15562 non-null object
Locus                      7329 non-null object
Excavation                 15967 non-null object
River                      2098 non-null object
Classification             437900 non-null object
Rights and Reproduction    24940 non-null object
Link Resource              494311 non-null object
Metadata Date              494311 non-null object
Repository                 494311 non-null object
Tags                       277566 non-null object
dtypes: bool(2), int64(3), object(39)
memory usage: 159.3+ MB

Analyzing textile classifications and object names

met_df[met_df['Object Name'].str.match('[Tt]extile',na=False) | met_df['Classification'].
       str.match('[Tt]extile',na=False)][['Object ID','Title','Department','Object Name','Classification']]
Object ID Title Department Object Name Classification
4819 5175 Mourning pictur American Decorative Arts Mourning picture Textiles
9645 10412 Length American Decorative Arts Length Textiles
11672 12685 Printed piece American Decorative Arts Printed piece Textiles
12003 13056 Curtain American Decorative Arts Curtain Textiles
12338 13462 Embroidered curtain American Decorative Arts Curtain Textiles
12344 13472 Embroidered Sampler American Decorative Arts Sampler Textiles
12345 13473 Quilt, Crazy pattern American Decorative Arts Quilt, Crazy pattern Textiles
12418 13549 Embroidered curtain American Decorative Arts Curtain Textiles
12419 13550 Badge of George Washington American Decorative Arts Badge Textiles
12420 13551 Badge of George Washington American Decorative Arts Badge Textiles
12421 13552 Badge of George Washington American Decorative Arts Badge Textiles
12422 13553 Badge of George Washington American Decorative Arts Badge Textiles
12423 13554 Badge of George Washington American Decorative Arts Badge Textiles
12424 13555 Badge of George Washington American Decorative Arts Badge Textiles
12425 13556 Purse American Decorative Arts Purse Textiles
12426 13557 Lace Fragment American Decorative Arts Lace Fragment Textiles
12427 13558 Beadwork panel American Decorative Arts Panel Textiles
12428 13559 Bedhanging American Decorative Arts Bed hanging Textiles
12429 13560 Bedhanging American Decorative Arts Bed hanging Textiles
12430 13561 Hanging American Decorative Arts Hanging Textiles
12431 13562 Hanging American Decorative Arts Hanging Textiles
12432 13563 Curtain American Decorative Arts Curtain Textiles
12433 13564 Bed Rug American Decorative Arts Bed Rug Textiles
12434 13565 Bed rug American Decorative Arts Bed rug Textiles
12435 13566 Sheet American Decorative Arts Sheet Textiles
12436 13567 Bedspread American Decorative Arts Bedspread Textiles
12437 13568 Bell Pull American Decorative Arts Bell Pull Textiles
12438 13569 Embroidered Bell Pull American Decorative Arts Bell Pull Textiles
12439 13571 Bonnet American Decorative Arts Bonnet Textiles
12440 13572 Bookmark American Decorative Arts Bookmark Textiles
... ... ... ... ... ...
494105 824442 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494106 824443 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494107 824444 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494108 824445 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494109 824446 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494110 824447 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494111 824448 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494112 824449 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494113 824450 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494122 824460 Baby's dress American Decorative Arts Dress Textiles
494232 824580 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494233 824581 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494234 824582 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494235 824583 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494236 824584 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494237 824585 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494238 824586 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494239 824587 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494240 824588 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494241 824589 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494280 824630 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494281 824631 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494282 824632 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494283 824633 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494284 824634 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494285 824635 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494286 824636 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494287 824637 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494288 824638 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books
494289 824639 Sheet of ribbon samples European Sculpture and Decorative Arts Sample book Textiles-Sample Books

33209 rows × 5 columns

ax = met_df[met_df['Object Name'].str.match('[Tt]extile',na=False)]['Object Name'].value_counts()[:15].plot(kind='barh')

ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)

# Switch off ticks
ax.tick_params(axis="both", which="both", bottom=False, top=False, labelbottom=True, left=False, right=False, labelleft=True)

# Draw vertical axis lines
vals = ax.get_xticks()
for tick in vals:
    ax.axvline(x=tick, linestyle='dashed', alpha=0.4, color='#eeeeee', zorder=1)

# Set x-axis label
ax.set_xlabel("Count", labelpad=20, weight='bold', size=12)

# Set y-axis label
ax.set_ylabel("Artist", labelpad=20, weight='bold', size=12)

# Format y-axis label
# ax.xaxis.set_major_formatter(StrMethodFormatter('{x:,g}'))
    
ax.invert_yaxis()
ax = met_df[met_df['Classification'].str.match('[Tt]extile',na=False)]['Classification'].value_counts()[:15].plot(kind='barh')

ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)

# Switch off ticks
ax.tick_params(axis="both", which="both", bottom=False, top=False, labelbottom=True, left=False, right=False, labelleft=True)

# Draw vertical axis lines
vals = ax.get_xticks()
for tick in vals:
    ax.axvline(x=tick, linestyle='dashed', alpha=0.4, color='#eeeeee', zorder=1)

# Set x-axis label
ax.set_xlabel("Count", labelpad=20, weight='bold', size=12)

# Set y-axis label
ax.set_ylabel("Artist", labelpad=20, weight='bold', size=12)

# Format y-axis label
# ax.xaxis.set_major_formatter(StrMethodFormatter('{x:,g}'))
    
ax.invert_yaxis()
# Object_Name -> Textile sample
# Histogram of how others are used
met_df[met_df['Object Name'].str.match('Textile sample',na=False)]['Classification'].value_counts()
Textiles-Woven                  888
Textiles-Printed                474
Textiles-Painted and Printed     28
Textiles                         22
Textiles-Dyed                     2
Textiles-Velvets                  2
Textiles-Laces                    1
Textiles-Painted                  1
Name: Classification, dtype: int64
# Object_Name -> Textile
# Histogram of how others are used
met_df[met_df['Object Name'].str.match('^Textile$',na=False)]['Classification'].value_counts()
Textiles-Woven                                     313
Textiles                                           115
Textiles-Printed                                   105
Textiles-Woven-Brocade                              38
Textiles-Costumes                                   26
Textiles-Embroidered                                24
Textiles-Tapestries                                 16
Textiles-Painted and Printed                        13
Textiles-Miscellaneous                              10
Textiles-Velvets                                     7
Textiles-Painted                                     3
Main dress-Womenswear                                3
Textiles-Dyed                                        3
Textiles-Laces                                       3
Textiles-Painted and/or Printed                      2
Textiles-Embroidered-Painted and Printed             1
Miscellaneous                                        1
Feathers-Costumes                                    1
Barkcloth                                            1
Miscellaneous|Textiles                               1
Textiles-Beadwork                                    1
Sculpture|Textiles|Textiles-Painted and Printed      1
Textiles-Ecclesiastical                              1
Textiles-Embroidered|Textiles-Laces                  1
Textiles-Methods and Materials                       1
Textiles-Featherwork                                 1
Name: Classification, dtype: int64
# Object_Name -> Textile fragment
# Histogram of how others are used
met_df[met_df['Object Name'].str.match('Textile fragment',na=False)]['Classification'].value_counts()
Textiles-Woven                     192
Textiles-Brocades                   26
Textiles                            24
Textiles-Printed                     8
Textiles-Velvets                     7
Textiles-Embroidered                 3
Textiles-Painted and/or Printed      3
Textiles-Painted and Printed         2
Textiles-Non-Woven                   1
Name: Classification, dtype: int64
# Object_Name -> Classification
# Histogram of how others are used
met_df[met_df['Classification'].str.match('[Tt]extile',na=False)]['Object Name'].value_counts()
Piece                                  8630
Fragment                               4479
Textile sample                         1409
Sample                                 1005
Sampler                                 903
Border                                  788
Panel                                   754
Textile                                 684
Ribbon                                  603
Galloon                                 545
Strip                                   457
Carpet                                  413
Edging                                  363
Tapestry                                342
Fringe                                  301
Band                                    268
Insertion                               268
Textile fragment                        254
Cover                                   240
Handkerchief                            217
Sleeve Band                             196
Tassel                                  187
Hanging                                 182
Length                                  165
Sample book                             161
Collar                                  161
Bag                                     160
Quilt                                   150
Rank Badge                              150
Flounce                                 147
                                       ... 
Barkcloth                                 1
Vertical Panel                            1
Coffin shield                             1
Wall covering fragment                    1
Temple Hanging with a Hindu Devotee       1
Wall panels                               1
Roundel and band                          1
Surcoat (Jinbaori)                        1
Ball                                      1
Case, Hanging                             1
Glove                                     1
Crib quilt                                1
Waistcoat panels                          1
Sleeve trimmings                          1
Needle Case                               1
Fragment of a sleeve band                 1
Cravat end or rabat                       1
Chasuble front with orphreys              1
Printed velvet                            1
Wedding Festival hanging                  1
Belts                                     1
Hanging with Crown and Escutcheon         1
Mittens                                   1
Cloth and border fragments                1
Decoration                                1
Altar hanging                             1
Chasuble front with orphrey band          1
Box and textile samples                   1
Galloons                                  1
Garment fragment (?)                      1
Name: Object Name, Length: 1261, dtype: int64
met_df[met_df['Classification'].str.match('[Tt]extile',na=False)]['Classification'].value_counts()
Textiles-Woven                                                                10994
Textiles-Laces                                                                 4962
Textiles-Embroidered                                                           4098
Textiles                                                                       3275
Textiles-Printed                                                               2559
Textiles-Trimmings                                                             1950
Textiles-Velvets                                                               1408
Textiles-Costumes                                                               672
Textiles-Tapestries                                                             646
Textiles-Rugs                                                                   621
Textiles-Methods and Materials                                                  257
Textiles-Painted and Printed                                                    196
Textiles-Sample Books                                                           188
Textiles-Painted and/or Printed                                                 139
Textiles-Implements                                                             116
Textiles-Featherwork                                                            109
Textiles-Beadwork                                                                95
Textiles-Ecclesiastical                                                          79
Textiles-Woven-Brocade                                                           78
Textiles-Woven|Textiles-Ecclesiastical                                           71
Textiles-Painted                                                                 67
Textiles-Dyed                                                                    60
Textiles-Dyed and Embroidered                                                    57
Textiles-Embroidered|Textiles-Ecclesiastical                                     56
Textiles-Brocades                                                                43
Textiles-Costumes-Accessories                                                    39
Textiles-Miscellaneous                                                           31
Textiles-Costumes-Secular                                                        29
Textiles-Costumes-Ecclesiastical                                                 29
Textiles-Painted and Dyed                                                        25
                                                                              ...  
Textiles-Woven|Textiles-Costumes                                                  1
Textiles-Embroidered|Textiles-Ecclesiastical|Textiles-Velvets                     1
Textiles-Paintings                                                                1
Textiles-Velvets|Textiles-Costumes-Ecclesiastical                                 1
Textiles-Embroidered|Textiles-Ecclesiastical|Textiles-Woven                       1
Textiles-Printed|Textiles-Ecclesiastical                                          1
Textiles-Embroidered|Textiles-Woven                                               1
Textiles-Methods and Materials|Textiles-Laces                                     1
Textiles-Beadwork|Textiles-Costumes                                               1
Textiles-Embroidered|Textiles-Dyed and Embroidered                                1
Textiles-Costumes|Textiles-Dyed and Embroidered                                   1
Textiles-Painted and Embroidered                                                  1
Textiles|Paintings                                                                1
Textiles-Woven|Textiles-Embroidered|Textiles-Ecclesiastical                       1
Textiles-Embroidered-Painted and Printed                                          1
Textiles-Velvets|Textiles-Woven|Textiles-Ecclesiastical                           1
Textiles-Embroidered|Textiles-Costumes-Ecclesiastical                             1
Textiles-Woven|Textiles-Laces                                                     1
Textiles-Painted-Reproductions                                                    1
Textiles-Costumes|Textiles-Beadwork                                               1
Textiles-Woven|Textiles-Ecclesiastical|Textiles-Embroidered|Textiles-Laces        1
Textiles-Costumes|Textiles-Embroidered                                            1
Textiles-Woven|Textiles-Printed|Textiles-Ecclesiastical                           1
Textiles-Laces|Textiles-Woven|Textiles-Ecclesiastical                             1
Textiles-Ecclesiastical|Textiles-Woven|Textiles-Embroidered                       1
Textiles-Costumes-Accessories|Beads-Costumes                                      1
Textiles-Painted|Textiles-Woven                                                   1
Textiles-Reproductions                                                            1
Textiles-Woven|Textiles-Laces|Textiles-Ecclesiastical                             1
Textiles-Woven|Textiles-Ecclesiastical|Textiles-Laces                             1
Name: Classification, Length: 93, dtype: int64

Examine some Credit Lines to extract a date

We can extract a year from the "Credit Line" column to set collection (P195) qualifier start time (P580). The object page on The Met web site has a "Provenance" section, but this does not seem accessible from the API or dump. It also seems to be different from Credit Line. Example:

https://www.metmuseum.org/art/collection/search/681504

Question - Is this a reasonable inference?

Question - Why is the above example inconsistent - Met API/database has no date, but object page says 1000 BC - 1 AD, which seems to be the incorrect range of dates

met_df['Credit Line'].sample(15)
356372                                    Rogers Fund, 1927
159234                               Museum Accession, 1974
480525    The Jefferson R. Burdick Collection, Gift of J...
22743                        Gift of William H. Riggs, 1913
159012    The Elisha Whittelsey Collection, The Elisha W...
217192                      Harris Brisbane Dick Fund, 1917
55814                            Gift of Susumu Ikuta, 1985
128730                      Bequest of Maria P. James, 1911
275474    The Jefferson R. Burdick Collection, Gift of J...
19630                      Bequest of George C. Stone, 1935
387428    The Jefferson R. Burdick Collection, Gift of J...
243562                                    Rogers Fund, 1917
443913    Museo Cao, Magdalena de Cao, Peru, Ministerio ...
231470                   Gift of Mrs. Henry T. Curtis, 1953
216522        Gift of Mr. and Mrs. Charles Wrightsman, 1982
Name: Credit Line, dtype: object

A method for extracing the year:

import re

for index, row in met_df.sample(15).iterrows(): 
    try:
        found = re.search('(.+?), ([0-9]+)', row['Credit Line']).group(2)
    except AttributeError:
        # AAA, ZZZ not found in the original string
        found = ''
    
    print (row['Credit Line'], '|', found)
    # print (found)
Conde Nast Fund and Everfast Fund, 1973 | 1973
Bequest of Maria P. James, 1911 | 1911
Fletcher Fund, 1924 | 1924
The Jefferson R. Burdick Collection, Gift of Jefferson R. Burdick | 
Gift of Dietrich von Bothmer, Distinguished Research Curator, Greek and Roman Art, 2011 | 2011
Harris Brisbane Dick Fund, 1946 | 1946
Bequest of George Blumenthal, 1941 | 1941
Private collection, New York | 
Rogers Fund, Transferred from the Library, 1941 | 1941
Bequest of Herbert Mitchell, 2008 | 2008
The Jefferson R. Burdick Collection, Gift of Jefferson R. Burdick | 
Gift of Mrs. Samuel Stiefel, 1940 | 1940
The Crosby Brown Collection of Musical Instruments, 1889 | 1889
Harris Brisbane Dick Fund, 1917 | 1917
Benaki Museum, Athens (10738) | 

Send Wikidata Query to pick up Met objects

Met objects are currently (April 2019) modeled slightly differently, so one goal of the project is to normalize this and make it consistent. There are currently two different methods to pick up Met objects:

  1. Anything with Met ID (P3634)
  2. Anything with inventory number (P217) qualified with collection (P195) set to Met (Q160236)

For a SPARQL query, these two are combined with UNION, and optional fields returned.

wikidata_api_url = 'https://query.wikidata.org/bigdata/namespace/wdq/sparql'

query = '''
SELECT DISTINCT ?item ?inventorynumber ?metid ?creator ?creatorLabel ?inception 
WHERE 
{
  {
    ?item p:P217 [ ps:P217 ?inventorynumber ; pq:P195 wd:Q160236 ]  .
  } UNION {
    ?item wdt:P3634 ?metid .
  }
  OPTIONAL { ?item p:P217 [ ps:P217 ?inventorynumber ; pq:P195 wd:Q160236 ]  . }
  OPTIONAL { ?item wdt:P3634 ?metid . }
  OPTIONAL { ?item wdt:P170 ?creator . }
  OPTIONAL { ?item wdt:P571 ?inception . }

  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
} 
'''

data = requests.post(wikidata_api_url, data={'query': query, 'format': 'json'}).json()

Examine some random records to understand the JSON structure

Now that we've made the SPARQL query, which may take 5-10 seconds, let's look at some of the raw JSON that is returned to understand how to parse it.

# Examine the return data by selecting a few random ones
import random
import pprint

pp = pprint.PrettyPrinter()
pp.pprint(random.choices(data['results']['bindings'], k=3))
[{'creator': {'type': 'uri',
              'value': 'http://www.wikidata.org/entity/Q2636828'},
  'creatorLabel': {'type': 'literal',
                   'value': 'Alan Shields',
                   'xml:lang': 'en'},
  'inception': {'datatype': 'http://www.w3.org/2001/XMLSchema#dateTime',
                'type': 'literal',
                'value': '1976-01-01T00:00:00Z'},
  'inventorynumber': {'type': 'literal', 'value': '1984.291'},
  'item': {'type': 'uri', 'value': 'http://www.wikidata.org/entity/Q19920757'},
  'metid': {'type': 'literal', 'value': '483117'}},
 {'creator': {'type': 'uri',
              'value': 'http://www.wikidata.org/entity/Q3120087'},
  'creatorLabel': {'type': 'literal',
                   'value': 'John La Farge',
                   'xml:lang': 'en'},
  'inception': {'datatype': 'http://www.w3.org/2001/XMLSchema#dateTime',
                'type': 'literal',
                'value': '1886-01-01T00:00:00Z'},
  'inventorynumber': {'type': 'literal', 'value': '67.55.177a–c'},
  'item': {'type': 'uri', 'value': 'http://www.wikidata.org/entity/Q20178373'},
  'metid': {'type': 'literal', 'value': '11389'}},
 {'inception': {'datatype': 'http://www.w3.org/2001/XMLSchema#dateTime',
                'type': 'literal',
                'value': '1730-01-01T00:00:00Z'},
  'inventorynumber': {'type': 'literal', 'value': '2005.365'},
  'item': {'type': 'uri', 'value': 'http://www.wikidata.org/entity/Q29385696'},
  'metid': {'type': 'literal', 'value': '504256'}}]

Convert the WDQ JSON result to a dataframe

Make life easier by converting the JSON to a Pandas Dataframe, which is basically a 2D spreadsheet-like data structure. We're going to also do some integrity checks as we import. Most of the data are strings and numbers, but the "inception" is a formal date string in the format +1984-01-01T00:00:00Z and it's possible Wikidata has dates that validate but are illogical, like year 0. It will error out on these, and show up in pink below.

Problem - It is also possible inception is set to "Unknown value" in Wikidata which is tricky to handle in Python.

In SPARQL parlance, it would be tested like this:

?item wdt:P571 ?date .

FILTER isBLANK(?date) .

We're have to figure out how to best represent this while doing our data work, since a Python dateTime module is quite strict. Some research indicates that there is quite a need for this type of function of handling outliers, but there is no simple or pat solution.

(https://stackoverflow.com/questions/6697770/allowing-invalid-dates-in-python-datetime)

import logging as logger
import numpy as np

resultarray = []
for item in data['results']['bindings']:
    # Need to fill in 0 and not None for int64, or this will be cast as float64
    metid = item['metid']['value'] if 'metid' in item else 0
    inventorynumber = item['inventorynumber']['value'] if 'inventorynumber' in item else None
    cl = item['creatorLabel']['value'] if 'creatorLabel' in item else None
    
    # Dates are weird - they are usually like +1984-01-01T00:00:00Z
    #   They may also be "unknown" with or without a start and end time
    try:
        inception = parse(item['inception']['value']) if 'inception' in item else None
    except (TypeError, ValueError):
        logger.warning('failed to parse QID %s - time %r', item['item']['value'], item['inception']['value'])
    
    resultarray.append({
        'qid': int(item['item']['value'].replace('http://www.wikidata.org/entity/Q','')),
        'metid': int(metid),
        'creatorLabel': cl,
        'inception': inception,
        'inventorynumber': inventorynumber,
        }
    )

# resultarray

# Create a Pandas dataframe    
wd_metitems_df = pd.DataFrame(resultarray)

# wd_metitems_df.astype(dtype={'metid':np.int64})

wd_metitems_df.info()
WARNING:root:failed to parse QID http://www.wikidata.org/entity/Q61730536 - time 't1466139731'
WARNING:root:failed to parse QID http://www.wikidata.org/entity/Q59767196 - time 't1466138755'
WARNING:root:failed to parse QID http://www.wikidata.org/entity/Q62761150 - time 't1415652024'
WARNING:root:failed to parse QID http://www.wikidata.org/entity/Q62759189 - time 't1415652016'
WARNING:root:failed to parse QID http://www.wikidata.org/entity/Q63434597 - time 't1445847308'
WARNING:root:failed to parse QID http://www.wikidata.org/entity/Q59770772 - time 't1466138991'
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10800 entries, 0 to 10799
Data columns (total 5 columns):
creatorLabel       9565 non-null object
inception          10416 non-null object
inventorynumber    10695 non-null object
metid              10800 non-null int64
qid                10800 non-null int64
dtypes: int64(2), object(3)
memory usage: 422.0+ KB

Examine some random records to check they are being imported correctly

wd_metitems_df.sample(15)
creatorLabel inception inventorynumber metid qid
6705 Robert Havell 1840-01-01 00:00:00+00:00 54.90.32 11042 20174458
4004 Emmanuel Tzanes 1663-01-01 00:00:00+00:00 33.79.18 437857 19913426
8214 anonymous 1350-01-01 00:00:00+00:00 25.120.289a-e 473891 20201854
2933 anonymous 1700-01-01 00:00:00+00:00 1976.100.13 436347 19913242
9540 None 0433-01-01 00:00:00+00:00 11.141 248499 29383763
1923 anonymous 1750-01-01 00:00:00+00:00 25.106.36 435939 19913745
1984 anonymous 1800-01-01 00:00:00+00:00 62.122.32 437665 19913880
10203 None 0265-01-01 00:00:00+00:00 55.11.5 254819 29383917
6913 Pavel Svinyin 1811-01-01 00:00:00+00:00 42.95.42 12729 20178059
6479 David Teniers the Younger 1655-01-01 00:00:00+00:00 1975.1.127 459069 20187112
5995 William Scott 1957-01-01 00:00:00+00:00 2007.49.87 492759 20190127
10725 None None None 38159 43712728
3366 Henry Colton Shumway 1843-01-01 00:00:00+00:00 2007.437 19718 19924795
8606 None 1800-01-01 00:00:00+00:00 1988.301 327369 29384521
5120 William P. Chappel 1870-01-01 00:00:00+00:00 54.90.514 10440 20175745

Wikidata items for The Met with 'anonymous' as creator

wd_metitems_df.creatorLabel.isin(['anonymous']).value_counts(normalize=True).plot.pie(autopct='%.0f')
<matplotlib.axes._subplots.AxesSubplot at 0x7f64a0e70128>
wd_metitems_df.creatorLabel.isna().value_counts(normalize=True).plot.pie(autopct='%.0f')
<matplotlib.axes._subplots.AxesSubplot at 0x7f64a840e400>
met_df['Artist Display Name'].notna().value_counts(normalize=True).plot.pie(autopct='%.0f')
<matplotlib.axes._subplots.AxesSubplot at 0x7f64a83cf240>
met_artist_notna_df = met_df[met_df['Artist Display Name']].notna().copy()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-14-0d2376b2e4ca> in <module>
----> 1 met_artist_notna_df = met_df[met_df['Artist Display Name']].notna().copy()
      2 

/srv/paws/lib/python3.6/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2915 
   2916         # Do we have a (boolean) 1d indexer?
-> 2917         if com.is_bool_indexer(key):
   2918             return self._getitem_bool_array(key)
   2919 

/srv/paws/lib/python3.6/site-packages/pandas/core/common.py in is_bool_indexer(key)
    122             if not lib.is_bool_array(key):
    123                 if isna(key).any():
--> 124                     raise ValueError(na_msg)
    125                 return False
    126             return True

ValueError: cannot index with vector containing NA / NaN values
met_df[met_df['Artist Display Name'].str.match('Anonymous')]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-59-2bfae3594be6> in <module>
----> 1 met_df[met_df['Artist Display Name'].str.match('Anonymous')]

/srv/paws/lib/python3.6/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2915 
   2916         # Do we have a (boolean) 1d indexer?
-> 2917         if com.is_bool_indexer(key):
   2918             return self._getitem_bool_array(key)
   2919 

/srv/paws/lib/python3.6/site-packages/pandas/core/common.py in is_bool_indexer(key)
    122             if not lib.is_bool_array(key):
    123                 if isna(key).any():
--> 124                     raise ValueError(na_msg)
    125                 return False
    126             return True

ValueError: cannot index with vector containing NA / NaN values

Wikidata items believed to be Met objects but missing Met Object ID statement

These items don't have Met Object ID (P3634) set but are in the list because the inventorynumber and collection->The Met Museum was set. We test to see if Met ID = 0.

wd_missing_metid_df = wd_metitems_df[wd_metitems_df['metid'] == 0].copy()

wd_missing_metid_df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 14 entries, 204 to 10677
Data columns (total 5 columns):
creatorLabel       14 non-null object
inception          14 non-null object
inventorynumber    14 non-null object
metid              14 non-null int64
qid                14 non-null int64
dtypes: int64(2), object(3)
memory usage: 672.0+ bytes

Outlier problems

The following entries had some issues with matching what was in the Met database - either these are outdated or there are some issues.

wd_missing_metid_df
creatorLabel inception inventorynumber metid qid
204 William-Adolphe Bouguereau 1873-01-01 00:00:00+00:00 L.2012.29 0 3555076
1601 anonymous 1800-01-01 00:00:00+00:00 24.80.488 0 19912903
9965 anonymous 1633-01-01 00:00:00+00:00 15.30.1 0 22097536
9967 anonymous 1633-01-01 00:00:00+00:00 15.30.2 0 22097547
9969 anonymous 1630-01-01 00:00:00+00:00 1971.186 0 22054880
9972 Rembrandt 1630-01-01 00:00:00+00:00 1971.186 0 22054880
10019 Johan Danckerts 1640-01-01 00:00:00+00:00 27.146 0 28608971
10279 David Vinckboons 1620-01-01 00:00:00+00:00 1976.100.20 0 30086888
10290 Adam Willaerts 1643-01-01 00:00:00+00:00 06.1303 0 30086759
10305 Albrecht Dürer 1526-01-01 00:00:00+00:00 9.73.120 0 40703137
10332 t1457747052 1655-01-01 00:00:00+00:00 74.55 0 62570242
10335 David Teniers the Younger 1655-01-01 00:00:00+00:00 74.55 0 62570242
10676 Philippe Pavy 1886-01-01 00:00:00+00:00 N.A.2016.9.3 0 57506362
10677 Jan van Goyen 1636-01-01 00:00:00+00:00 06.290 0 57170461

Use Pandas equivalent of a database join

Do an "inner" join that makes a new dataframe based on the Met database (met_df) but adds a new columns from the Wikidata query (wd_missing_metid_df) that supplies qid and Object Number/inventory number

merged_todo_metid_df = pd.merge(met_df, wd_missing_metid_df, how='inner', left_on='Object Number', right_on='inventorynumber')

Test some rows for sanity:

merged_todo_metid_df[['Object Number','Object ID','qid']].info()
<class 'pandas.core.frame.DataFrame'>
Index: 0 entries
Data columns (total 3 columns):
Object Number    0 non-null object
Object ID        0 non-null int64
qid              0 non-null int64
dtypes: int64(2), object(1)
memory usage: 0.0+ bytes

Good - we fixed 82 items missing the Met ID on May 24, 2019, so now we are in sync.

Generate Quickstatements to fix the problem

In case you need to create Quickstatements, here they are:

# To generate Quickstatements, iterate over the rows
# Desired output: Q43742238|P3634|26606
QS_ADDMISSING_METID='Q%s|P3634|"%d"'

for index, row in merged_todo_metid_df.iterrows(): 
    print (QS_ADDMISSING_METID % (row['qid'], row['Object ID']))

Wikidata items believed to be Met objects but missing inventory number statement

These items don't have inventory number set but are in the list because Met Object ID (P3634) was set. We test to see if Wikidata results for Met items has inventorynumber set to None.

FIX for this would be to generate and ingest Quickstatements to fill in inventory number.

Something like:

Q61876946|P217|"2003.161"|P195|Q160236

wd_missing_inventory_df = wd_metitems_df[wd_metitems_df['inventorynumber'].isnull()].copy()

wd_missing_inventory_df.sample(10)
creatorLabel inception inventorynumber metid qid
10786 Katsushika Hokusai 1825-01-01 00:00:00+00:00 None 54925 60920142
10729 Makron None None 248697 42186356
10795 Giovanni Paolo Panini 1754-01-01 00:00:00+00:00 None 437245 3094651
10735 None 0589-01-01 00:00:00+00:00 None 548211 28670008
10694 Winslow Homer 1899-01-01 00:00:00+00:00 None 20011478 62022405
10797 None 1550-01-01 00:00:00+00:00 None 812566 61781455
10789 Katsushika Hokusai None None 78638 60682065
10695 Pablo Picasso 1914-01-01 00:00:00+00:00 None 490563 61884489
10765 Kitagawa Utamaro None None 36631 60590430
10758 Gaspare Diziani None None 338609 28732893

Use Pandas equivalent of a database join

Do an "inner" join that makes a new dataframe based on the Met database (met_df) but adds a new columns from the Wikidata query (wd_missing_inventory_df) that supplies qid and matched metid

merged_todo_inventorynumber_df = pd.merge(met_df, wd_missing_inventory_df, how='inner', left_on='Object ID', right_on='metid')

merged_todo_inventorynumber_df[['Object Number','Object ID','qid']].info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 104 entries, 0 to 103
Data columns (total 3 columns):
Object Number    104 non-null object
Object ID        104 non-null int64
qid              104 non-null int64
dtypes: int64(2), object(1)
memory usage: 3.2+ KB
merged_todo_inventorynumber_df[['Object Number','Object ID','qid']].sample(5)
Object Number Object ID qid
91 L.2014.77 503040 63082710
44 2013.730 78801 60661765
63 80.3.384 338609 28732893
87 1998.456.3 490686 61781317
58 2005.100.20 283092 29881716

Generate Quickstatements to fix the problem

# To generate Quickstatements, iterate over the rows
# Desired output: Q61876946|P217|32767|P195|Q160236

# It is possible that the inventory number does exist already, but is missing the qualifier
# For example, it may have:
#   Q61750964|P217|"66.109"
# but not:
#   Q61750964|P217|"66.109"|P195|Q160236

# We could just subtract

QS_ADDMISSING_INVENTORYNUMBER='Q%s|P217|"%s"|P195|Q160236'
QS_ADDMISSING_COLLECTION='Q%s|P195|Q160236|P217|"%s"'

for index, row in merged_todo_inventorynumber_df.iterrows(): 
    print (QS_ADDMISSING_INVENTORYNUMBER % (row['qid'], row['Object Number']))
    print (QS_ADDMISSING_COLLECTION % (row['qid'], row['Object Number']))
Q61750964|P217|"66.109"|P195|Q160236
Q61750964|P195|Q160236|P217|"66.109"
Q30993455|P217|"2016.797.21"|P195|Q160236
Q30993455|P195|Q160236|P217|"2016.797.21"
Q30994036|P217|"2016.797.17"|P195|Q160236
Q30994036|P195|Q160236|P217|"2016.797.17"
Q61750993|P217|"43.120.1208a, b"|P195|Q160236
Q61750993|P195|Q160236|P217|"43.120.1208a, b"
Q30063003|P217|"36.25.508"|P195|Q160236
Q30063003|P195|Q160236|P217|"36.25.508"
Q60590430|P217|"JP152"|P195|Q160236
Q60590430|P195|Q160236|P217|"JP152"
Q60579810|P217|"JP555"|P195|Q160236
Q60579810|P195|Q160236|P217|"JP555"
Q60628715|P217|"JP1122"|P195|Q160236
Q60628715|P195|Q160236|P217|"JP1122"
Q60601286|P217|"JP2739"|P195|Q160236
Q60601286|P195|Q160236|P217|"JP2739"
Q60567840|P217|"JP3118"|P195|Q160236
Q60567840|P195|Q160236|P217|"JP3118"
Q60568037|P217|"JP3129"|P195|Q160236
Q60568037|P195|Q160236|P217|"JP3129"
Q43712728|P217|"1982.220.7"|P195|Q160236
Q43712728|P195|Q160236|P217|"1982.220.7"
Q62794859|P217|"36.100.70"|P195|Q160236
Q62794859|P195|Q160236|P217|"36.100.70"
Q61751040|P217|"30.32.15"|P195|Q160236
Q61751040|P195|Q160236|P217|"30.32.15"
Q43742393|P217|"19.103.2"|P195|Q160236
Q43742393|P195|Q160236|P217|"19.103.2"
Q60628584|P217|"1996.463"|P195|Q160236
Q60628584|P195|Q160236|P217|"1996.463"
Q28126677|P217|"1991.134"|P195|Q160236
Q28126677|P195|Q160236|P217|"1991.134"
Q60590216|P217|"JP990"|P195|Q160236
Q60590216|P195|Q160236|P217|"JP990"
Q47544982|P217|"1985.227.1"|P195|Q160236
Q47544982|P195|Q160236|P217|"1985.227.1"
Q43376787|P217|"1999.263a, b"|P195|Q160236
Q43376787|P195|Q160236|P217|"1999.263a, b"
Q61746498|P217|"1989.363.123"|P195|Q160236
Q61746498|P195|Q160236|P217|"1989.363.123"
Q60920142|P217|"JP1016"|P195|Q160236
Q60920142|P195|Q160236|P217|"JP1016"
Q60572478|P217|"JP1121"|P195|Q160236
Q60572478|P195|Q160236|P217|"JP1121"
Q60595333|P217|"JP2394"|P195|Q160236
Q60595333|P195|Q160236|P217|"JP2394"
Q60706622|P217|"JIB5"|P195|Q160236
Q60706622|P195|Q160236|P217|"JIB5"
Q61409206|P217|"JIB69"|P195|Q160236
Q61409206|P195|Q160236|P217|"JIB69"
Q61413284|P217|"JIB80"|P195|Q160236
Q61413284|P195|Q160236|P217|"JIB80"
Q61748802|P217|"10.7.4"|P195|Q160236
Q61748802|P195|Q160236|P217|"10.7.4"
Q61876908|P217|"2002.325"|P195|Q160236
Q61876908|P195|Q160236|P217|"2002.325"
Q43648711|P217|"2015.300.301a–c"|P195|Q160236
Q43648711|P195|Q160236|P217|"2015.300.301a–c"
Q63243745|P217|"SL.17.2011.22.4"|P195|Q160236
Q63243745|P195|Q160236|P217|"SL.17.2011.22.4"
Q61781621|P217|"2011.127"|P195|Q160236
Q61781621|P195|Q160236|P217|"2011.127"
Q60682065|P217|"2013.736a–f"|P195|Q160236
Q60682065|P195|Q160236|P217|"2013.736a–f"
Q60704425|P217|"2013.738a, b"|P195|Q160236
Q60704425|P195|Q160236|P217|"2013.738a, b"
Q60570674|P217|"2013.852a, b"|P195|Q160236
Q60570674|P195|Q160236|P217|"2013.852a, b"
Q60571703|P217|"2013.853"|P195|Q160236
Q60571703|P195|Q160236|P217|"2013.853"
Q60571061|P217|"2013.858"|P195|Q160236
Q60571061|P195|Q160236|P217|"2013.858"
Q60571356|P217|"2013.859"|P195|Q160236
Q60571356|P195|Q160236|P217|"2013.859"
Q60704878|P217|"2013.875"|P195|Q160236
Q60704878|P195|Q160236|P217|"2013.875"
Q60704659|P217|"2013.878"|P195|Q160236
Q60704659|P195|Q160236|P217|"2013.878"
Q60701873|P217|"2013.881"|P195|Q160236
Q60701873|P195|Q160236|P217|"2013.881"
Q60571569|P217|"2013.897"|P195|Q160236
Q60571569|P195|Q160236|P217|"2013.897"
Q60705589|P217|"2013.726"|P195|Q160236
Q60705589|P195|Q160236|P217|"2013.726"
Q60661034|P217|"2013.729a–c"|P195|Q160236
Q60661034|P195|Q160236|P217|"2013.729a–c"
Q60661765|P217|"2013.730"|P195|Q160236
Q60661765|P195|Q160236|P217|"2013.730"
Q41601734|P217|"29.158.485"|P195|Q160236
Q41601734|P195|Q160236|P217|"29.158.485"
Q30063394|P217|"2009.300.3275a–c"|P195|Q160236
Q30063394|P195|Q160236|P217|"2009.300.3275a–c"
Q582428|P217|"24.232"|P195|Q160236
Q582428|P195|Q160236|P217|"24.232"
Q30263483|P217|"42.30.17a, b"|P195|Q160236
Q30263483|P195|Q160236|P217|"42.30.17a, b"
Q54965918|P217|"58.75.3"|P195|Q160236
Q54965918|P195|Q160236|P217|"58.75.3"
Q30262521|P217|"42.30.18a, b"|P195|Q160236
Q30262521|P195|Q160236|P217|"42.30.18a, b"
Q60646192|P217|"L.2011.66.56a, b"|P195|Q160236
Q60646192|P195|Q160236|P217|"L.2011.66.56a, b"
Q42186356|P217|"12.231.1"|P195|Q160236
Q42186356|P195|Q160236|P217|"12.231.1"
Q42149613|P217|"17.230.5"|P195|Q160236
Q42149613|P195|Q160236|P217|"17.230.5"
Q36446060|P217|"24.97.21a, b"|P195|Q160236
Q36446060|P195|Q160236|P217|"24.97.21a, b"
Q36446060|P217|"24.97.21a, b"|P195|Q160236
Q36446060|P195|Q160236|P217|"24.97.21a, b"
Q42244789|P217|"46.11.7"|P195|Q160236
Q42244789|P195|Q160236|P217|"46.11.7"
Q3209564|P217|"1976.646"|P195|Q160236
Q3209564|P195|Q160236|P217|"1976.646"
Q29881716|P217|"2005.100.20"|P195|Q160236
Q29881716|P195|Q160236|P217|"2005.100.20"
Q61876946|P217|"2003.161"|P195|Q160236
Q61876946|P195|Q160236|P217|"2003.161"
Q61781606|P217|"1987.394.544"|P195|Q160236
Q61781606|P195|Q160236|P217|"1987.394.544"
Q26221327|P217|"62.151"|P195|Q160236
Q26221327|P195|Q160236|P217|"62.151"
Q61876710|P217|"1999.171.1, .2"|P195|Q160236
Q61876710|P195|Q160236|P217|"1999.171.1, .2"
Q28732893|P217|"80.3.384"|P195|Q160236
Q28732893|P195|Q160236|P217|"80.3.384"
Q56604898|P217|"26.72.24"|P195|Q160236
Q56604898|P195|Q160236|P217|"26.72.24"
Q56604898|P217|"26.72.24"|P195|Q160236
Q56604898|P195|Q160236|P217|"26.72.24"
Q23688157|P217|"06.1322.2"|P195|Q160236
Q23688157|P195|Q160236|P217|"06.1322.2"
Q18338529|P217|"19.73.66"|P195|Q160236
Q18338529|P195|Q160236|P217|"19.73.66"
Q61876882|P217|"2003.20.4"|P195|Q160236
Q61876882|P195|Q160236|P217|"2003.20.4"
Q18339638|P217|"19.73.152"|P195|Q160236
Q18339638|P195|Q160236|P217|"19.73.152"
Q61876879|P217|"17.3.4"|P195|Q160236
Q61876879|P195|Q160236|P217|"17.3.4"
Q61781468|P217|"2009.436.1a–w"|P195|Q160236
Q61781468|P195|Q160236|P217|"2009.436.1a–w"
Q18338468|P217|"68.793.66"|P195|Q160236
Q18338468|P195|Q160236|P217|"68.793.66"
Q18338961|P217|"19.73.82"|P195|Q160236
Q18338961|P195|Q160236|P217|"19.73.82"
Q61781441|P217|"53.600.261(5)"|P195|Q160236
Q61781441|P195|Q160236|P217|"53.600.261(5)"
Q3395798|P217|"49.7.21"|P195|Q160236
Q3395798|P195|Q160236|P217|"49.7.21"
Q17275914|P217|"14.40.626–27"|P195|Q160236
Q17275914|P195|Q160236|P217|"14.40.626–27"
Q44214076|P217|"49.7.22"|P195|Q160236
Q44214076|P195|Q160236|P217|"49.7.22"
Q3094651|P217|"52.63.2"|P195|Q160236
Q3094651|P195|Q160236|P217|"52.63.2"
Q25936897|P217|"66.25"|P195|Q160236
Q25936897|P195|Q160236|P217|"66.25"
Q25936897|P217|"66.25"|P195|Q160236
Q25936897|P195|Q160236|P217|"66.25"
Q31073129|P217|"1979.317.1"|P195|Q160236
Q31073129|P195|Q160236|P217|"1979.317.1"
Q31068759|P217|"1979.317.2ab"|P195|Q160236
Q31068759|P195|Q160236|P217|"1979.317.2ab"
Q31070828|P217|"1979.317.3ab"|P195|Q160236
Q31070828|P195|Q160236|P217|"1979.317.3ab"
Q29049154|P217|"1990.38.1"|P195|Q160236
Q29049154|P195|Q160236|P217|"1990.38.1"
Q933665|P217|"1990.38.3"|P195|Q160236
Q933665|P195|Q160236|P217|"1990.38.3"
Q61884489|P217|"CTO.135"|P195|Q160236
Q61884489|P195|Q160236|P217|"CTO.135"
Q5506360|P217|"2016.237.33"|P195|Q160236
Q5506360|P195|Q160236|P217|"2016.237.33"
Q61781317|P217|"1998.456.3"|P195|Q160236
Q61781317|P195|Q160236|P217|"1998.456.3"
Q60596830|P217|"CTO.128"|P195|Q160236
Q60596830|P195|Q160236|P217|"CTO.128"
Q60517079|P217|"SL.17.2014.1.3"|P195|Q160236
Q60517079|P195|Q160236|P217|"SL.17.2014.1.3"
Q61479355|P217|"SL.17.2014.1.9"|P195|Q160236
Q61479355|P195|Q160236|P217|"SL.17.2014.1.9"
Q63082710|P217|"L.2014.77"|P195|Q160236
Q63082710|P195|Q160236|P217|"L.2014.77"
Q7107718|P217|"31.4.2"|P195|Q160236
Q7107718|P195|Q160236|P217|"31.4.2"
Q28670008|P217|"07.229.1a, b"|P195|Q160236
Q28670008|P195|Q160236|P217|"07.229.1a, b"
Q61781516|P217|"2011.599.1a"|P195|Q160236
Q61781516|P195|Q160236|P217|"2011.599.1a"
Q61627764|P217|"63.350.207.135.17"|P195|Q160236
Q61627764|P195|Q160236|P217|"63.350.207.135.17"
Q44178853|P217|"2014.520"|P195|Q160236
Q44178853|P195|Q160236|P217|"2014.520"
Q55619837|P217|"SL.1.2016.39.1"|P195|Q160236
Q55619837|P195|Q160236|P217|"SL.1.2016.39.1"
Q61781550|P217|"1972.717.1"|P195|Q160236
Q61781550|P195|Q160236|P217|"1972.717.1"
Q61781403|P217|"1972.717.4"|P195|Q160236
Q61781403|P195|Q160236|P217|"1972.717.4"
Q56651549|P217|"SL.2.2018.1.2"|P195|Q160236
Q56651549|P195|Q160236|P217|"SL.2.2018.1.2"
Q61781450|P217|"2016.113"|P195|Q160236
Q61781450|P195|Q160236|P217|"2016.113"
Q56697085|P217|"SL.2.2018.21.20"|P195|Q160236
Q56697085|P195|Q160236|P217|"SL.2.2018.21.20"
Q61781455|P217|"2018.756"|P195|Q160236
Q61781455|P195|Q160236|P217|"2018.756"