CPW
  • Home
  • About
  • Bonus
  • Datasets
  • Knowledge
  • Python
  • Text
  • Analysis
  • Visualization
  • Resources

After Workshop Activity

Overview

This activity has two complementary goals. First, it gives you a chance to rehearse the workflow we followed throughout the workshop using a small, controlled dataset. Second, it provides a clear sequence of steps you can reuse and adapt to your own provenance material.

Starting from a single CSV containing unstructured provenance text, you will produce a set of connected, structured tables that you can analyze in a notebook—or export as Gephi-ready nodes and edges for network analysis.

You will build three core datasets:

  • Objects table (one row per artwork)
  • Provenance events table (one row per provenance event sentence). This will be our master spreadsheet.
  • Parties table (one row per party mention; later consolidated into one row per unique party)

Once identifiers are consistent across all three tables, your data can be handled like a relational database inside Google Colab: you can join, filter, and query across objects, events, and parties.

Download this workflow as a PDF


Dataset for this activity

Since the full Art Institute of Chicago dataset was too large to analyze within the workshop, and because we wanted to practice the full process of moving from unstructured to structured provenance data, on the final day we worked with two artworks by Paul Gauguin.

In this activity, you will focus instead on all Pablo Ruiz Picasso artworks in the Art Institute of Chicago dataset. The object-level metadata is intentionally minimal, because our main focus is the provenance text. This provenance text has not been cleaned or structured—you will work with it exactly as it was downloaded from the AIC.

Dataset: Picasso Artworks at the Art Institute of Chicago


Step-by-step workflow

Part A — Prepare the data

  1. Open the file subset_picasso_AIC.csv.
  2. Inspect the dataset:
    • Review the column names (headers).
    • Preview the first rows to understand what each column contains.
  3. Create a smaller subset table that keeps only:
    • object_id
    • provenance_text

This gives you one row per artwork, with its full provenance text in a single column.

Note

This “objects subset” is your starting point. Everything else (events, parties, networks) will be derived from this table.

Part B — Turn provenance text into provenance events

Provenance text is typically written as a sequence of statements. To structure it, treat each sentence as a discrete provenance event (for example: a sale, a transfer, an auction, an acquisition, a bequest).

  1. Split provenance_text into sentences.
  2. Create a provenance events table where each sentence becomes one row.
  3. Assign a unique identifier to each event.

Your provenance events table should include:

provenance_event_id object_id provenance_event_text
PE_0001 29909 Miss Sally Heard Lewis (1870–1963), Portland, Ore.
PE_0002 29909 Sold, Christie’s, London, June 19, 1964, lot 90, to Richards.
PE_0003 29909 Michael Smith, New York, acquired the work by purchase.

The information contained in this table is just an example

At the end of this step, you have:

  • a table of objects
  • a table of provenance events linked to objects via object_id

Part C — Extract parties (people and institutions)

Now extract entities from each provenance event sentence, focusing on:

  • People (collectors, dealers, artists, etc.)
  • Institutions (museums, galleries, auction houses, etc.)

Create a parties table (mentions of people/institutions). At this stage you will usually have multiple rows per provenance event, because one sentence can mention several parties.

Include the following columns:

  • object_id
  • provenance_event_id
  • party_id (an ID you assign at extraction time)
  • party_name_raw (the exact string as it appears in the sentence)
object_id provenance_event_id party_id party_name_raw
29909 PE_0002 PM_0001 Christie’s
29909 PE_0002 PM_0002 Richards
29909 PE_0001 PM_0003 Miss Sally Heard Lewis
29909 PE_0003 PM_0004 Michael Smith

The information contained in this table is just an example

By this point, you have three connected datasets:

  • Objects (object_id)
  • Provenance events (provenance_event_id, linked to object_id)
  • Party mentions (party_id, linked to provenance_event_id and object_id)
Tip

“Raw” party names are extremely valuable. Never overwrite them. Always keep a party_name_raw column, even after standardization.

Part D — Clean and standardize party names (important)

Cleaning is not cosmetic—it is structural. If the same party appears under multiple spellings, your analysis and networks will treat them as different entities unless you standardize them.

You cannot rely on party_id alone, because the same party may appear in different forms, such as:

  • “AIC”
  • “Art Institute of Chicago”
  • “Art Institue of Chicago” (typo)

In this dataset, there are two common issues to fix:

  • AIC and Art Institute refer to the same institution (the Art Institute of Chicago).
  • The artist name (written in capital letters too) refers to Pablo Picasso and should not become an “institution” or a generic party label like “The artists”.

If you only take “unique values” based on IDs, these will still survive as separate parties.

Create a cleaning dictionary (mapping file)

  1. Export a list of unique raw party names (and their current party_id) to CSV or Excel.
  2. Open the file in Google Sheets / Excel.
  3. Add two new columns:
    • party_id_correct
    • name_correct
  4. For each raw variant, assign:
    • the correct standardized party ID (party_id_correct)
    • the correct standardized party name (name_correct)

This mapping file becomes your rulebook for merging duplicates and correcting typos.

This mapping file becomes your rulebook for merging duplicates and correcting typos.

Example mapping file (cleaning dictionary):

party_id party_name_raw party_id_correct name_correct
PM_0007 AIC P_0001 Art Institute of Chicago
PM_0134 Art Institute P_0001 Art Institute of Chicago
PM_0135 Art Institue of Chicago P_0001 Art Institute of Chicago
PM_0201 PICASSO P_0002 Pablo Picasso
PM_0202 The artists P_0002 Pablo Picasso

The information contained in this table is just an example

Apply the dictionary

  1. Save the mapping file.
  2. Upload it back to Google Colab.
  3. Apply it to your parties table to add:
    • party_id_correct
    • name_correct

After this step, parties are cleaned and consistent.

Warning

Do not delete raw variants. Keep them and add corrected fields. You want traceability: you should always be able to answer “what exactly was written in the source text?”

Part E — Optional enrichment (depends on your project)

Once party names are standardized, you may want to enrich your parties table depending on your research questions.

Common enrichment options:

  • Retrieve extra attributes from Wikidata (country, occupation, founding date, birth/death dates).
  • Add type (person vs institution).
  • Add gender, nationality, city, or other metadata.
  • Split personal names into first_name / last_name (more useful for people than institutions).
Note

Enrichment is optional. It becomes most useful when you want analytical questions that depend on attributes (birth dates, places, nationality, gender, institutional type, etc.).

Part F — Complete the provenance events master table

Once you have created your provenance events table, it should look like this (one row per event sentence):

object_id provenance_event_id provenance_event_text
29909 PE_0001 Miss Sally Heard Lewis (1870–1963), Portland, Ore.
29909 PE_0002 Sold, Christie’s, London, June 19, 1964, lot 90, to Richards.
29909 PE_0003 Michael Smith, New York, acquired the work by purchase.

The information contained in this table is just an example

Now expand it into a richer event table that supports analysis and visualization.

1) Split parties into separate numbered columns

If you haven’t done this already, take the parties mentioned in each provenance_event_text and split them into separate columns:

  • party_1, party_2, party_3, …

2) Add party IDs using your party dictionary

Use your mapping file (the dictionary with corrected IDs and names) to assign IDs for each party column:

  • party_id_1 matches party_1
  • party_id_2 matches party_2
  • …

3) Extract dates and create an event date column

Extract dates from provenance_event_text and create:

  • provenance_event_date

Important: some dates belong to party descriptions (not the event). Define a rule to avoid mixing them.

One practical rule:

  • If you see two dates separated by an en dash or hyphen (e.g., 1873–1948), treat them as a lifespan, not an event date.

4) Extract location and create an event location column

Extract location information from provenance_event_text and create:

  • provenance_event_location

5) Extract the method of transfer

Extract the method of transfer and create:

  • method_of_transfer

If your extraction model does not capture this reliably, define a controlled list and guide extraction using that vocabulary, for example:

  • purchase
  • gift
  • bequest
  • inheritance
  • sale
  • exchange

Final expected columns

At the end, your event-based master table will contain columns such as:

object_id provenance_event_id provenance_event_text party_id_1 party_1 party_id_2 party_2 method_of_transfer provenance_event_location provenance_event_date
29909 PE_0001 Sold, Christie’s, London, June 19, 1964, lot 90, to Richards. P_0012 Christie’s P_0345 Richards sale London 1964-06-19
29909 PE_0002 Michael Smith, New York, acquired the work by purchase. P_0789 Michael Smith P_0001 Art Institute of Chicago purchase New York 19xx-xx-xx

The information contained in this table is just an example

Note

This table is structured by provenance event, so object_id repeats across multiple rows. That repetition is correct: one object can have many provenance events.

Data analysis in Google Colab

At this stage you should have three main spreadsheets:

  1. A provenance events master table (one row per provenance event)
  2. An objects table (one row per object)
  3. A parties table (one row per person or institution)

Upload all three into Google Colab and load them as dataframes.

The key point is to preserve exact column names (for example object_id, provenance_event_id, party_id_correct), because those are what you will use to connect tables.

Once the tables share consistent IDs, you can join them and run analyses that combine information across the three datasets. This is the same logic as working with a relational database—but done inside a notebook.

Example analysis question

Which objects were acquired through a purchase (method_of_transfer = purchase) by parties born between X and Y?

To get reliable results, be explicit in your notebook prompts about:

  • which file/table you want to use (events, objects, or parties)
  • which columns you want to filter or compare
  • which IDs you want to use to connect tables
Tip

If you enriched parties with Wikidata, your dataset becomes much more powerful: you can use birth dates, nationality, gender, locations, and identifiers to run richer queries and produce more meaningful interpretations.

Network time — Create Gephi-ready files (Nodes + Edges)

Once your parties are cleaned and your IDs are consistent, you can export networks for Gephi.

1) Nodes file

Create a CSV for nodes with column names in lowercase:

  • id (your final, cleaned party ID)
  • label (your final, cleaned party name)

Optional: add extra attributes as additional columns (for example country, gender, type).

2) Edges file

Create a CSV for edges with column names:

  • source
  • target

In this file, you connect IDs only (not labels).

What you connect depends on your network design. Common options include:

  • Party → Party (co-appearance in the same provenance event; co-ownership; transaction relationships)
  • Party → Object (bipartite network)
  • Party → Provenance event (event-based network)

3) Load into Gephi

  1. Upload your nodes CSV first.
  2. Upload your edges CSV second.
  3. Run a layout and basic metrics, then start exploring the graph.
Note

If you paste your exact CSV column names and tell me which network you want (Party–Party, Party–Object, or Party–Event), I can rewrite this “Network time” section with the precise edge logic for your chosen design.