{
"cells": [
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"obj2info = pd.read_csv(\"../data/processed/OM_obj_to_info.csv\")\n",
"file2obj = pd.read_csv(\"../data/processed/OM_file_to_obj.csv\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"file_counts = file2obj[\"obj_num\"].value_counts()\n",
"# file2obj"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"obj_num\n",
"durom.1969.406 249\n",
"durom.1973.47 191\n",
"DUROM.1954.Spalding29.W 112\n",
"durom.1960.2332 101\n",
"durom.2014.1 76\n",
" ... \n",
"durom.2006.46.32 1\n",
"durom.2006.44.16 1\n",
"durom.2006.45.194 1\n",
"durom.2006.46.13 1\n",
"durom.1964.183 1\n",
"Name: count, Length: 12642, dtype: int64"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"file_counts"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Images per instance | \n",
" Number of instances | \n",
" Number of images | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 3 | \n",
" 696 | \n",
" 2088 | \n",
"
\n",
" \n",
" 1 | \n",
" 4 | \n",
" 703 | \n",
" 2812 | \n",
"
\n",
" \n",
" 2 | \n",
" 5 | \n",
" 360 | \n",
" 1800 | \n",
"
\n",
" \n",
" 3 | \n",
" 6 | \n",
" 853 | \n",
" 5118 | \n",
"
\n",
" \n",
" 4 | \n",
" 7 | \n",
" 471 | \n",
" 3297 | \n",
"
\n",
" \n",
" 5 | \n",
" 8 | \n",
" 223 | \n",
" 1784 | \n",
"
\n",
" \n",
" 6 | \n",
" 9 | \n",
" 110 | \n",
" 990 | \n",
"
\n",
" \n",
" 7 | \n",
" 10+ | \n",
" 456 | \n",
" 7836 | \n",
"
\n",
" \n",
" 8 | \n",
" Total | \n",
" 3872 | \n",
" 25725 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Images per instance Number of instances Number of images\n",
"0 3 696 2088\n",
"1 4 703 2812\n",
"2 5 360 1800\n",
"3 6 853 5118\n",
"4 7 471 3297\n",
"5 8 223 1784\n",
"6 9 110 990\n",
"7 10+ 456 7836\n",
"8 Total 3872 25725"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"distribution_df = pd.DataFrame()\n",
"distribution_df[\"Images per instance\"] = file_counts.value_counts().sort_index().index\n",
"distribution_df[\"Number of instances\"] = file_counts.value_counts().sort_index().values\n",
"distribution_df[\"Number of images\"] = (\n",
" distribution_df[\"Images per instance\"] * distribution_df[\"Number of instances\"]\n",
")\n",
"num_instances_10plus = distribution_df[distribution_df[\"Images per instance\"] >= 10][\n",
" \"Number of instances\"\n",
"].sum()\n",
"num_images_10plus = distribution_df[distribution_df[\"Images per instance\"] >= 10][\n",
" \"Number of images\"\n",
"].sum()\n",
"distribution_df = distribution_df[\n",
" (distribution_df[\"Images per instance\"] < 10) & (distribution_df[\"Images per instance\"] > 2)\n",
"]\n",
"\n",
"distribution_df = pd.concat(\n",
" [\n",
" distribution_df,\n",
" pd.DataFrame(\n",
" {\n",
" \"Images per instance\": [\"10+\"],\n",
" \"Number of instances\": [num_instances_10plus],\n",
" \"Number of images\": [num_images_10plus],\n",
" }\n",
" ),\n",
" ],\n",
" ignore_index=True,\n",
")\n",
"\n",
"# append total\n",
"distribution_df = pd.concat(\n",
" [\n",
" distribution_df,\n",
" pd.DataFrame(\n",
" {\n",
" \"Images per instance\": [\"Total\"],\n",
" \"Number of instances\": [distribution_df[\"Number of instances\"].sum()],\n",
" \"Number of images\": [distribution_df[\"Number of images\"].sum()],\n",
" }\n",
" ),\n",
" ],\n",
" ignore_index=True,\n",
")\n",
"# distribution_df = distribution_df[['Images per instance', 'Number of images', 'Number of instances']]\n",
"distribution_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This distribution broadly follows that from Winterbottom's paper, with a few minor differences. \n",
"\n",
"I am not expecting it to be exactly the same, as winterbottom did not use the database at all, instead just looked at the images"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Assessing for alternative text labels"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [],
"source": [
"full_df = pd.read_excel(\"../data/raw/Durham_University_Museums_data.xlsx\")\n",
"full_df = full_df.filter(regex=r\"^(?!Unnamed).*$\")\n",
"full_df = full_df.dropna(subset=[\"description\"])"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Column | \n",
" Null Percentage | \n",
" unique_values | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" object_number | \n",
" 0.00 | \n",
" 53460 | \n",
"
\n",
" \n",
" 4 | \n",
" description | \n",
" 0.00 | \n",
" 1191 | \n",
"
\n",
" \n",
" 6 | \n",
" material | \n",
" 4.43 | \n",
" 6442 | \n",
"
\n",
" \n",
" 1 | \n",
" object_name | \n",
" 8.96 | \n",
" 26163 | \n",
"
\n",
" \n",
" 22 | \n",
" alternative_number | \n",
" 18.30 | \n",
" 46165 | \n",
"
\n",
" \n",
" 13 | \n",
" production.place | \n",
" 34.42 | \n",
" 3234 | \n",
"
\n",
" \n",
" 12 | \n",
" production.period | \n",
" 40.90 | \n",
" 414 | \n",
"
\n",
" \n",
" 3 | \n",
" reproduction.reference | \n",
" 50.23 | \n",
" 76 | \n",
"
\n",
" \n",
" 11 | \n",
" production.date.end | \n",
" 50.90 | \n",
" 6923 | \n",
"
\n",
" \n",
" 10 | \n",
" production.date.start | \n",
" 51.04 | \n",
" 127 | \n",
"
\n",
" \n",
" 2 | \n",
" other_name | \n",
" 58.72 | \n",
" 968 | \n",
"
\n",
" \n",
" 9 | \n",
" number_of_parts | \n",
" 62.08 | \n",
" 949 | \n",
"
\n",
" \n",
" 8 | \n",
" physical_description | \n",
" 73.54 | \n",
" 485 | \n",
"
\n",
" \n",
" 14 | \n",
" field_coll.place | \n",
" 77.88 | \n",
" 812 | \n",
"
\n",
" \n",
" 16 | \n",
" field_coll.method | \n",
" 83.38 | \n",
" 546 | \n",
"
\n",
" \n",
" 18 | \n",
" content.subject | \n",
" 87.25 | \n",
" 1449 | \n",
"
\n",
" \n",
" 7 | \n",
" technique | \n",
" 87.58 | \n",
" 22 | \n",
"
\n",
" \n",
" 21 | \n",
" association.subject | \n",
" 88.35 | \n",
" 516 | \n",
"
\n",
" \n",
" 15 | \n",
" field_coll.notes | \n",
" 91.09 | \n",
" 773 | \n",
"
\n",
" \n",
" 5 | \n",
" label.text | \n",
" 91.69 | \n",
" 78 | \n",
"
\n",
" \n",
" 20 | \n",
" association.person | \n",
" 95.54 | \n",
" 289 | \n",
"
\n",
" \n",
" 17 | \n",
" content.person.name | \n",
" 95.89 | \n",
" 247 | \n",
"
\n",
" \n",
" 19 | \n",
" association.period | \n",
" 97.70 | \n",
" 36718 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Column Null Percentage unique_values\n",
"0 object_number 0.00 53460\n",
"4 description 0.00 1191\n",
"6 material 4.43 6442\n",
"1 object_name 8.96 26163\n",
"22 alternative_number 18.30 46165\n",
"13 production.place 34.42 3234\n",
"12 production.period 40.90 414\n",
"3 reproduction.reference 50.23 76\n",
"11 production.date.end 50.90 6923\n",
"10 production.date.start 51.04 127\n",
"2 other_name 58.72 968\n",
"9 number_of_parts 62.08 949\n",
"8 physical_description 73.54 485\n",
"14 field_coll.place 77.88 812\n",
"16 field_coll.method 83.38 546\n",
"18 content.subject 87.25 1449\n",
"7 technique 87.58 22\n",
"21 association.subject 88.35 516\n",
"15 field_coll.notes 91.09 773\n",
"5 label.text 91.69 78\n",
"20 association.person 95.54 289\n",
"17 content.person.name 95.89 247\n",
"19 association.period 97.70 36718"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"null_percentage = (full_df.isnull().sum() / len(full_df)) * 100\n",
"desc_df = pd.DataFrame(\n",
" {\"Column\": null_percentage.index, \"Null Percentage\": null_percentage.values}\n",
")\n",
"desc_df[\"Null Percentage\"] = desc_df[\"Null Percentage\"].round(2)\n",
"desc_df = desc_df.sort_values(by=\"Null Percentage\")\n",
"desc_df[\"unique_values\"] = full_df.nunique().values\n",
"desc_df"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [],
"source": [
"def get_distribution(df, column, lower_bound=2):\n",
" distribution = pd.DataFrame()\n",
" col_counts = df[column].value_counts()\n",
" distribution[f\"{column}s per instance\"] = col_counts.value_counts().sort_index().index\n",
" distribution[\"Number of instances\"] = col_counts.value_counts().sort_index().values\n",
" distribution[f\"Number of {column}s\"] = (\n",
" distribution[f\"{column}s per instance\"] * distribution[\"Number of instances\"]\n",
" )\n",
" num_instances_10_50 = distribution[\n",
" (distribution[f\"{column}s per instance\"] >= 10)\n",
" & (distribution[f\"{column}s per instance\"] < 50)\n",
" ][\"Number of instances\"].sum()\n",
" num_images_10_50 = distribution[\n",
" (distribution[f\"{column}s per instance\"] >= 10)\n",
" & (distribution[f\"{column}s per instance\"] < 50)\n",
" ][f\"Number of {column}s\"].sum()\n",
" num_instances_50_100 = distribution[\n",
" (distribution[f\"{column}s per instance\"] >= 50)\n",
" & (distribution[f\"{column}s per instance\"] < 100)\n",
" ][\"Number of instances\"].sum()\n",
" num_images_50_100 = distribution[\n",
" (distribution[f\"{column}s per instance\"] >= 50)\n",
" & (distribution[f\"{column}s per instance\"] < 100)\n",
" ][f\"Number of {column}s\"].sum()\n",
" num_instances_100_1000 = distribution[\n",
" (distribution[f\"{column}s per instance\"] >= 100)\n",
" & (distribution[f\"{column}s per instance\"] < 1000)\n",
" ][\"Number of instances\"].sum()\n",
" num_images_100_1000 = distribution[\n",
" (distribution[f\"{column}s per instance\"] >= 100)\n",
" & (distribution[f\"{column}s per instance\"] < 1000)\n",
" ][f\"Number of {column}s\"].sum()\n",
" num_instances_1000plus = distribution[distribution[f\"{column}s per instance\"] >= 1000][\n",
" \"Number of instances\"\n",
" ].sum()\n",
" num_images_1000plus = distribution[distribution[f\"{column}s per instance\"] >= 1000][\n",
" f\"Number of {column}s\"\n",
" ].sum()\n",
"\n",
" distribution = distribution[\n",
" (distribution[f\"{column}s per instance\"] < 10)\n",
" & (distribution[f\"{column}s per instance\"] > lower_bound)\n",
" ]\n",
"\n",
" distribution = pd.concat(\n",
" [\n",
" distribution,\n",
" pd.DataFrame(\n",
" {\n",
" f\"{column}s per instance\": [\"10-50\"],\n",
" \"Number of instances\": [num_instances_10_50],\n",
" f\"Number of {column}s\": [num_images_10_50],\n",
" }\n",
" ),\n",
" pd.DataFrame(\n",
" {\n",
" f\"{column}s per instance\": [\"50-100\"],\n",
" \"Number of instances\": [num_instances_50_100],\n",
" f\"Number of {column}s\": [num_images_50_100],\n",
" }\n",
" ),\n",
" pd.DataFrame(\n",
" {\n",
" f\"{column}s per instance\": [\"100-1000\"],\n",
" \"Number of instances\": [num_instances_100_1000],\n",
" f\"Number of {column}s\": [num_images_100_1000],\n",
" }\n",
" ),\n",
" pd.DataFrame(\n",
" {\n",
" f\"{column}s per instance\": [\"1000+\"],\n",
" \"Number of instances\": [num_instances_1000plus],\n",
" f\"Number of {column}s\": [num_images_1000plus],\n",
" }\n",
" ),\n",
" ],\n",
" ignore_index=True,\n",
" )\n",
"\n",
" distribution = pd.concat(\n",
" [\n",
" distribution,\n",
" pd.DataFrame(\n",
" {\n",
" f\"{column}s per instance\": [\"Total\"],\n",
" \"Number of instances\": [distribution[\"Number of instances\"].sum()],\n",
" f\"Number of {column}s\": [distribution[f\"Number of {column}s\"].sum()],\n",
" }\n",
" ),\n",
" ],\n",
" ignore_index=True,\n",
" )\n",
" # rename columns\n",
" return distribution"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" object_names per instance | \n",
" Number of instances | \n",
" Number of object_names | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 3 | \n",
" 93 | \n",
" 279 | \n",
"
\n",
" \n",
" 1 | \n",
" 4 | \n",
" 57 | \n",
" 228 | \n",
"
\n",
" \n",
" 2 | \n",
" 5 | \n",
" 53 | \n",
" 265 | \n",
"
\n",
" \n",
" 3 | \n",
" 6 | \n",
" 32 | \n",
" 192 | \n",
"
\n",
" \n",
" 4 | \n",
" 7 | \n",
" 27 | \n",
" 189 | \n",
"
\n",
" \n",
" 5 | \n",
" 8 | \n",
" 24 | \n",
" 192 | \n",
"
\n",
" \n",
" 6 | \n",
" 9 | \n",
" 27 | \n",
" 243 | \n",
"
\n",
" \n",
" 7 | \n",
" 10-50 | \n",
" 227 | \n",
" 4921 | \n",
"
\n",
" \n",
" 8 | \n",
" 50-100 | \n",
" 51 | \n",
" 3683 | \n",
"
\n",
" \n",
" 9 | \n",
" 100-1000 | \n",
" 65 | \n",
" 17027 | \n",
"
\n",
" \n",
" 10 | \n",
" 1000+ | \n",
" 7 | \n",
" 20758 | \n",
"
\n",
" \n",
" 11 | \n",
" Total | \n",
" 663 | \n",
" 47977 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" object_names per instance Number of instances Number of object_names\n",
"0 3 93 279\n",
"1 4 57 228\n",
"2 5 53 265\n",
"3 6 32 192\n",
"4 7 27 189\n",
"5 8 24 192\n",
"6 9 27 243\n",
"7 10-50 227 4921\n",
"8 50-100 51 3683\n",
"9 100-1000 65 17027\n",
"10 1000+ 7 20758\n",
"11 Total 663 47977"
]
},
"execution_count": 107,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"get_distribution(full_df, \"object_name\")"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" materials per instance | \n",
" Number of instances | \n",
" Number of materials | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 3 | \n",
" 30 | \n",
" 90 | \n",
"
\n",
" \n",
" 1 | \n",
" 4 | \n",
" 16 | \n",
" 64 | \n",
"
\n",
" \n",
" 2 | \n",
" 5 | \n",
" 14 | \n",
" 70 | \n",
"
\n",
" \n",
" 3 | \n",
" 6 | \n",
" 9 | \n",
" 54 | \n",
"
\n",
" \n",
" 4 | \n",
" 7 | \n",
" 10 | \n",
" 70 | \n",
"
\n",
" \n",
" 5 | \n",
" 8 | \n",
" 6 | \n",
" 48 | \n",
"
\n",
" \n",
" 6 | \n",
" 9 | \n",
" 5 | \n",
" 45 | \n",
"
\n",
" \n",
" 7 | \n",
" 10-50 | \n",
" 88 | \n",
" 1975 | \n",
"
\n",
" \n",
" 8 | \n",
" 50-100 | \n",
" 21 | \n",
" 1409 | \n",
"
\n",
" \n",
" 9 | \n",
" 100-1000 | \n",
" 43 | \n",
" 13030 | \n",
"
\n",
" \n",
" 10 | \n",
" 1000+ | \n",
" 12 | \n",
" 34036 | \n",
"
\n",
" \n",
" 11 | \n",
" Total | \n",
" 254 | \n",
" 50891 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" materials per instance Number of instances Number of materials\n",
"0 3 30 90\n",
"1 4 16 64\n",
"2 5 14 70\n",
"3 6 9 54\n",
"4 7 10 70\n",
"5 8 6 48\n",
"6 9 5 45\n",
"7 10-50 88 1975\n",
"8 50-100 21 1409\n",
"9 100-1000 43 13030\n",
"10 1000+ 12 34036\n",
"11 Total 254 50891"
]
},
"execution_count": 100,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"get_distribution(full_df, \"material\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Production date could be used for a regression task, and the other fields could be used for a classification task."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Year"
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" production.date.starts per instance | \n",
" Number of instances | \n",
" Number of production.date.starts | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" 275 | \n",
" 275 | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" 129 | \n",
" 258 | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" 75 | \n",
" 225 | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" 72 | \n",
" 288 | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" 45 | \n",
" 225 | \n",
"
\n",
" \n",
" 5 | \n",
" 6 | \n",
" 32 | \n",
" 192 | \n",
"
\n",
" \n",
" 6 | \n",
" 7 | \n",
" 20 | \n",
" 140 | \n",
"
\n",
" \n",
" 7 | \n",
" 8 | \n",
" 16 | \n",
" 128 | \n",
"
\n",
" \n",
" 8 | \n",
" 9 | \n",
" 21 | \n",
" 189 | \n",
"
\n",
" \n",
" 9 | \n",
" 10-50 | \n",
" 199 | \n",
" 4226 | \n",
"
\n",
" \n",
" 10 | \n",
" 50-100 | \n",
" 39 | \n",
" 2661 | \n",
"
\n",
" \n",
" 11 | \n",
" 100-1000 | \n",
" 41 | \n",
" 10259 | \n",
"
\n",
" \n",
" 12 | \n",
" 1000+ | \n",
" 4 | \n",
" 7110 | \n",
"
\n",
" \n",
" 13 | \n",
" Total | \n",
" 968 | \n",
" 26176 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" production.date.starts per instance Number of instances \\\n",
"0 1 275 \n",
"1 2 129 \n",
"2 3 75 \n",
"3 4 72 \n",
"4 5 45 \n",
"5 6 32 \n",
"6 7 20 \n",
"7 8 16 \n",
"8 9 21 \n",
"9 10-50 199 \n",
"10 50-100 39 \n",
"11 100-1000 41 \n",
"12 1000+ 4 \n",
"13 Total 968 \n",
"\n",
" Number of production.date.starts \n",
"0 275 \n",
"1 258 \n",
"2 225 \n",
"3 288 \n",
"4 225 \n",
"5 192 \n",
"6 140 \n",
"7 128 \n",
"8 189 \n",
"9 4226 \n",
"10 2661 \n",
"11 10259 \n",
"12 7110 \n",
"13 26176 "
]
},
"execution_count": 101,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"get_distribution(full_df, \"production.date.start\", lower_bound=0)"
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" production.date.ends per instance | \n",
" Number of instances | \n",
" Number of production.date.ends | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" 285 | \n",
" 285 | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" 120 | \n",
" 240 | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" 63 | \n",
" 189 | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" 46 | \n",
" 184 | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" 32 | \n",
" 160 | \n",
"
\n",
" \n",
" 5 | \n",
" 6 | \n",
" 37 | \n",
" 222 | \n",
"
\n",
" \n",
" 6 | \n",
" 7 | \n",
" 26 | \n",
" 182 | \n",
"
\n",
" \n",
" 7 | \n",
" 8 | \n",
" 20 | \n",
" 160 | \n",
"
\n",
" \n",
" 8 | \n",
" 9 | \n",
" 19 | \n",
" 171 | \n",
"
\n",
" \n",
" 9 | \n",
" 10-50 | \n",
" 210 | \n",
" 4562 | \n",
"
\n",
" \n",
" 10 | \n",
" 50-100 | \n",
" 41 | \n",
" 2588 | \n",
"
\n",
" \n",
" 11 | \n",
" 100-1000 | \n",
" 47 | \n",
" 11609 | \n",
"
\n",
" \n",
" 12 | \n",
" 1000+ | \n",
" 3 | \n",
" 5696 | \n",
"
\n",
" \n",
" 13 | \n",
" Total | \n",
" 949 | \n",
" 26248 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" production.date.ends per instance Number of instances \\\n",
"0 1 285 \n",
"1 2 120 \n",
"2 3 63 \n",
"3 4 46 \n",
"4 5 32 \n",
"5 6 37 \n",
"6 7 26 \n",
"7 8 20 \n",
"8 9 19 \n",
"9 10-50 210 \n",
"10 50-100 41 \n",
"11 100-1000 47 \n",
"12 1000+ 3 \n",
"13 Total 949 \n",
"\n",
" Number of production.date.ends \n",
"0 285 \n",
"1 240 \n",
"2 189 \n",
"3 184 \n",
"4 160 \n",
"5 222 \n",
"6 182 \n",
"7 160 \n",
"8 171 \n",
"9 4562 \n",
"10 2588 \n",
"11 11609 \n",
"12 5696 \n",
"13 26248 "
]
},
"execution_count": 102,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"get_distribution(full_df, \"production.date.end\", lower_bound=0)"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" start_year | \n",
" end_year | \n",
" year_diff | \n",
" mid_year | \n",
"
\n",
" \n",
" \n",
" \n",
" 2 | \n",
" -3000 | \n",
" -3000 | \n",
" 0 | \n",
" -3000 | \n",
"
\n",
" \n",
" 142 | \n",
" -600 | \n",
" -332 | \n",
" 268 | \n",
" -466 | \n",
"
\n",
" \n",
" 143 | \n",
" -1069 | \n",
" -716 | \n",
" 353 | \n",
" -893 | \n",
"
\n",
" \n",
" 147 | \n",
" -716 | \n",
" -332 | \n",
" 384 | \n",
" -524 | \n",
"
\n",
" \n",
" 148 | \n",
" -716 | \n",
" -332 | \n",
" 384 | \n",
" -524 | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 60081 | \n",
" 218 | \n",
" 222 | \n",
" 4 | \n",
" 220 | \n",
"
\n",
" \n",
" 60082 | \n",
" 1996 | \n",
" 1996 | \n",
" 0 | \n",
" 1996 | \n",
"
\n",
" \n",
" 60083 | \n",
" 2016 | \n",
" 2016 | \n",
" 0 | \n",
" 2016 | \n",
"
\n",
" \n",
" 60084 | \n",
" 1996 | \n",
" 1996 | \n",
" 0 | \n",
" 1996 | \n",
"
\n",
" \n",
" 60085 | \n",
" 1996 | \n",
" 1996 | \n",
" 0 | \n",
" 1996 | \n",
"
\n",
" \n",
"
\n",
"
26016 rows × 4 columns
\n",
"
"
],
"text/plain": [
" start_year end_year year_diff mid_year\n",
"2 -3000 -3000 0 -3000\n",
"142 -600 -332 268 -466\n",
"143 -1069 -716 353 -893\n",
"147 -716 -332 384 -524\n",
"148 -716 -332 384 -524\n",
"... ... ... ... ...\n",
"60081 218 222 4 220\n",
"60082 1996 1996 0 1996\n",
"60083 2016 2016 0 2016\n",
"60084 1996 1996 0 1996\n",
"60085 1996 1996 0 1996\n",
"\n",
"[26016 rows x 4 columns]"
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"year_df = pd.DataFrame()\n",
"year_df[\"start_year\"] = full_df[\"production.date.start\"]\n",
"year_df[\"end_year\"] = full_df[\"production.date.end\"]\n",
"year_df = year_df.dropna()\n",
"\n",
"non_numeric_instances = year_df[\n",
" pd.to_numeric(year_df[\"start_year\"], errors=\"coerce\").isna()\n",
" | pd.to_numeric(year_df[\"end_year\"], errors=\"coerce\").isna()\n",
"]\n",
"# get non-numeric instances\n",
"year_df = year_df[~year_df.index.isin(non_numeric_instances.index)]\n",
"year_df[\"start_year\"] = year_df[\"start_year\"].astype(int)\n",
"year_df[\"end_year\"] = year_df[\"end_year\"].astype(int)\n",
"year_df[\"year_diff\"] = year_df[\"end_year\"] - year_df[\"start_year\"]\n",
"\n",
"year_df[\"mid_year\"] = year_df[\"start_year\"] + year_df[\"year_diff\"] / 2\n",
"year_df[\"mid_year\"] = year_df[\"mid_year\"].apply(lambda x: int(np.floor(x)))\n",
"year_df"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAHHCAYAAACiOWx7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABEHUlEQVR4nO3df3zP9f7/8ft7s723sZ/YZjWzIhQdoTQRsTasRE4dUaFFTtvJIp2UJCpZ0RDJOZkU+XUcdRCWn6Xlxwr5kVJ+xraKmZ/bbK/vH332+nrb8DJv29vcrpeLS72er8f79Xq83k/b7l7v5/s9m2EYhgAAAHBBbhXdAAAAwNWA0AQAAGABoQkAAMACQhMAAIAFhCYAAAALCE0AAAAWEJoAAAAsIDQBAABYQGgCAACwgNAEVGLDhw+XzWYrl3O1bdtWbdu2NbdXrVolm82mefPmlcv5e/furTp16pTLucrq+PHjevLJJxUaGiqbzaakpCSnn+NS5txms2n48OFO7wGorAhNwFVi2rRpstls5h8vLy+FhYUpNjZW48eP17Fjx5xynoMHD2r48OHatGmTU47nTK7cmxVvvPGGpk2bpr///e/66KOP9Nhjj523tk6dOrLZbIqOji51/7/+9S/z78LGjRuvSL9vvvmmbDabli5dWur+Tp06yd/fXwcPHrwi5wdcjgHgqpCammpIMkaMGGF89NFHxtSpU4033njDiImJMWw2mxEREWFs3rzZ4TEFBQXGqVOnLuk8GzZsMCQZqampl/S4vLw8Iy8vz9xeuXKlIcmYO3fuJR2nrL3l5+cbp0+fdtq5roQWLVoYd911l6XaiIgIw8vLy3BzczMOHTpUYn+bNm0MLy8vQ5KxYcMGc/xS5lyS8corr5x3f35+vtG4cWPjhhtuME6ePOmwb86cOYYkY+LEiZbOBVQG3GkCrjIdO3bUo48+qj59+mjIkCFaunSpvvjiC2VnZ6tz5846deqUWVulShV5eXld0X5OnjwpSfL09JSnp+cVPdeFeHh4yG63V9j5rcjOzlZAQIDl+rvuukvVqlXT7NmzHcYPHDigL7/8UnFxcSUe48w59/Dw0JQpU7Rnzx6NHDnSHD927JiSkpJ05513qn///k4514UUFRXp9OnTV/w8wMUQmoBKoF27dnr55Ze1d+9effzxx+Z4aetb0tLS1KpVKwUEBKhatWqqX7++XnzxRUl/rkO6/fbbJUl9+vQxX/6ZNm2apD/XLTVq1EgZGRm6++675ePjYz723DVNxQoLC/Xiiy8qNDRUVatWVefOnbV//36Hmjp16qh3794lHnv2MS/WW2lrmk6cOKFBgwYpPDxcdrtd9evX19tvvy3DMBzqbDabEhMTtWDBAjVq1Eh2u1233HKLlixZUvoTfo7s7GzFx8crJCREXl5e+stf/qIPP/zQ3F+8vmv37t1atGiR2fuePXsueFwvLy89+OCDmjlzpsP4J598osDAQMXGxpZ4TGlznpeXp2effVY1a9aUr6+vOnfurAMHDli6tuJg9Pbbb2v79u2SpKFDhyo7O1tTpkyRm5ubcnJylJSUZD7PdevW1ejRo1VUVORwrLffflstW7ZU9erV5e3trWbNmpW65q14PmbMmKFbbrlFdrvd8lwAV1KVim4AgHM89thjevHFF7Vs2TL17du31Jpt27bpvvvu06233qoRI0bIbrdr165dWrt2rSSpYcOGGjFihIYNG6Z+/fqpdevWkqSWLVuax/jjjz/UsWNHde/eXY8++qhCQkIu2Nfrr78um82mf/7zn8rOzlZKSoqio6O1adMmeXt7W74+K72dzTAMde7cWStXrlR8fLyaNGmipUuXavDgwfr111/1zjvvONR/9dVXmj9/vp5++mn5+vpq/Pjx6tatm/bt26fq1auft69Tp06pbdu22rVrlxITExUZGam5c+eqd+/eysnJ0YABA9SwYUN99NFHevbZZ3X99ddr0KBBkqSaNWte9Lp79OihmJgY/fzzz7rxxhslSTNnztRf//pXeXh4WHrunnzySX388cfq0aOHWrZsqRUrVpR6l+p8Ro0apQULFuipp55SSkqKJk6cqMGDB6tx48Y6efKk2rRpo19//VVPPfWUateura+//lpDhgzRoUOHlJKSYh5n3Lhx6ty5s3r27Kn8/HzNmjVLDz30kBYuXFiinxUrVmjOnDlKTExUjRo1XH6RP64RFf36IABritc0nb1+5Vz+/v7GbbfdZm6/8sorxtlf5u+8844hyfjtt9/Oe4wLrRtq06aNIcmYPHlyqfvatGljbhevabruuuuM3Nxcc7x4Lcy4cePMsYiICKNXr14XPeaFeuvVq5cRERFhbi9YsMCQZLz22msOdX/9618Nm81m7Nq1yxyTZHh6ejqM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Qwft27dPeXl5uvfee+Xr66vRo0crLy9PkydPdnafAAAAFapMd5oGDBig5s2b68iRI/L29jbHu3btquXLlzutOQAAAFdRpjtNX375pb7++mt5eno6jNepU0e//vqrUxoDAABwJWW601RUVKTCwsIS4wcOHJCvr+9lNwUAAOBqyhSaYmJilJKSYm7bbDYdP35cr7zyCr9aBQAAVEplenluzJgxio2N1c0336zTp0+rR48e+umnn1SjRg198sknzu4RAACgwpUpNF1//fXavHmzZs2apS1btuj48eOKj49Xz549HRaGAwAAVBZlCk2SVKVKFT366KPO7AUAAMBllSk0TZ8+/YL7H3/88TI1AwAA4KrKFJoGDBjgsF1QUKCTJ0/K09NTPj4+hCYAAFDplOndc0eOHHH4c/z4ce3cuVOtWrViITgAAKiUyvy7585Vr149vfnmmyXuQgEAAFQGTgtN0p+Lww8ePOjMQwIAALiEMq1p+uyzzxy2DcPQoUOH9O677+quu+5ySmMAAACupEyhqUuXLg7bNptNNWvWVLt27TRmzBhn9AUAAOBSyhSaioqKnN0HAACAS3PqmiYAAIDKqkx3mgYOHGi5duzYsWU5BQAAgEspU2j67rvv9N1336mgoED169eXJP34449yd3dX06ZNzTqbzeacLgEAACpYmULT/fffL19fX3344YcKDAyU9OcHXvbp00etW7fWoEGDnNokAABARSvTmqYxY8Zo1KhRZmCSpMDAQL322mu8ew4AAFRKZQpNubm5+u2330qM//bbbzp27NhlNwUAAOBqyhSaunbtqj59+mj+/Pk6cOCADhw4oP/85z+Kj4/Xgw8+6OweAQAAKlyZ1jRNnjxZzz33nHr06KGCgoI/D1SliuLj4/XWW285tUEAAABXUKbQ5OPjo0mTJumtt97Szz//LEm68cYbVbVqVac2BwAA4Cou68MtDx06pEOHDqlevXqqWrWqDMNwVl8AAAAupUx3mv744w89/PDDWrlypWw2m3766SfdcMMNio+PV2BgIO+gAwAAl6TOC4skSXZ3Q8l3SI2GL1VeoePnPe55M64iWjOV6U7Ts88+Kw8PD+3bt08+Pj7m+N/+9jctWbLEac0BAAC4ijLdaVq2bJmWLl2q66+/3mG8Xr162rt3r1MaAwAAcCVlutN04sQJhztMxQ4fPiy73X7Z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ptFw62+ssrsZGtm8qNS5uRLPdfErRVa4dGgyDEP/+Mc/9N///lerVq1SZGSkw/5mzZrJw8NDy5cvV7du3SRJO3fu1L59+xQVFSVJioqK0uuvv67s7GwFBwdL+vNffn5+frr55pvNmnPTa1pamnmM0tjtdtnt9hLjHh4elfIbZGW9rsqAuXFtzI9ryyuyKa/w8kIT83txZXmOS5ubK/FcX8oxXTo0JSQkaObMmfr000/l6+trrkHy9/eXt7e3/P39FR8fr4EDByooKEh+fn76xz/+oaioKN15552SpJiYGN1888167LHHlJycrMzMTA0dOlQJCQlm6Onfv7/effddPf/883riiSe0YsUKzZkzR4sWLaqwawcAAK7Fpd8999577+no0aNq27atatWqZf6ZPXu2WfPOO+/ovvvuU7du3XT33XcrNDRU8+fPN/e7u7tr4cKFcnd3V1RUlB599FE9/vjjGjFihFkTGRmpRYsWKS0tTX/5y180ZswY/fvf/+bjBgAAgMml7zQZxsVX23t5eWnixImaOHHieWsiIiIuunisbdu2+u677y65RwAAcG1w6TtNAAAAroLQBAAAYAGhCQAAwAJCEwAAgAWEJgAAAAsITQAAABYQmgAAACxw6c9pAgAArq3OC9fOb8/gThMAAIAFhCYAAAALCE0AAAAWEJoAAAAsIDQBAABYQGgCAACwgNAEAABgAaEJAADAAkITAACABYQmAAAACwhNAAAAFhCaAAAALCA0AQAAWEBoAgAAsIDQBAAAYAGhCQAAwAJCEwAAgAWEJgAAAAsITQAAABYQmgAAACwgNAEAAFhAaAIAALCA0AQAAGABoQkAAMACQhMAAIAFhCYAAAALCE0AAAAWEJoAAAAsIDQBAABYQGgCAACwgNAEAABgQZWKbgAAADhPnRcWWarb82bcFe6k8uFOEwAAgAWEJgAAAAsITQAAABYQmgAAACwgNAEAAFhAaAIAALCA0AQAAGABoQkAAMACQhMAAIAFhCYAAAALCE0AAAAWEJoAAAAsIDQBAABYUKWiGwAAAOWvzguLLlqz5824cujk6kFoAgDgKmEl6ODKITQBQCXFnQTAuQhNAAC4AFe8i+SKPVUkQhOuGfyrG7h2XOzr3e5uKPmOcmoGlQbvnjvHxIkTVadOHXl5ealFixZav359RbcEAABcAHeazjJ79mwNHDhQkydPVosWLZSSkqLY2Fjt3LlTwcHBFd0eAFzVuNuLqx2h6Sxjx45V37591adPH0nS5MmTtWjRIk2dOlUvvPBCBXcHoCJV1h/4rrZmxdX6saKy/t1ASYSm/5Ofn6+MjAwNGTLEHHNzc1N0dLTS09MrsDMAl8PVfgg76wesq10XLoz5qhwITf/n999/V2FhoUJCQhzGQ0JC9MMPP5Soz8vLU15enrl99OhRSdLhw4dVUFBwZZstRwUFBTp58qT++OMPeXh4VHQ7l6XKmRMXrfnjjz/KoRPnqIi5aTFq+UVr1g1pXw6d/MlKP+X5Ta7uc3PM/7e7GRp6W5GavDRfeUW2S+rn7OOcD9+8L0+VIkMnTxapSoGbCs+aH1S8C83NlfgefezYMUmSYRgX783pZ79GjBo1Sq+++mqJ8cjIyAroBs5SY0xFd3D14zn8/3pUdAO4IObHdZ1vbq7k95djx47J39//gjWEpv9To0YNubu7Kysry2E8KytLoaGhJeqHDBmigQMHmttFRUU6fPiwqlevLput8vyrJTc3V+Hh4dq/f7/8/Pwquh2chblxbcyPa2N+XFd5z41hGDp27JjCwsIuWkto+j+enp5q1qyZli9fri5dukj6MwgtX75ciYmJJertdrvsdrvDWEBAQDl0WjH8/Pz4xuKimBvXxvy4NubHdZXn3FzsDlMxQtNZBg4cqF69eql58+a64447lJKSohMnTpjvpgMAANcuQtNZ/va3v+m3337TsGHDlJmZqSZNmmjJkiUlFocDAIBrD6HpHImJiaW+HHetstvteuWVV0q8FImKx9y4NubHtTE/rsuV58ZmWHmPHQAAwDWO3z0HAABgAaEJAADAAkITAACABYQmAAAACwhN17BFixapRYsW8vb2VmBgoPmhnsX27dunuLg4+fj4KDg4WIMHD9aZM2ccalatWqWmTZvKbrerbt26mjZtWonzTJw4UXXq1JGXl5datGih9evXX8Grqlzy8vLUpEkT2Ww2bdq0yWHfli1b1Lp1a3l5eSk8PFzJycklHj937lw1aNBAXl5eaty4sRYvXuyw3zAMDRs2TLVq1ZK3t7eio6P1008/XclLuqrt2bNH8fHxioyMlLe3t2688Ua98sorys/Pd6hjblwb35OuvFGjRun222+Xr6+vgoOD1aVLF+3cudOh5vTp00pISFD16tVVrVo1devWrcRv5XDWzyGnMXBNmjdvnhEYGGi89957xs6dO41t27YZs2fPNvefOXPGaNSokREdHW189913xuLFi40aNWoYQ4YMMWt++eUXw8fHxxg4cKCxfft2Y8KECYa7u7uxZMkSs2bWrFmGp6enMXXqVGPbtm1G3759jYCAACMrK6tcr/dq9cwzzxgdO3Y0JBnfffedOX706FEjJCTE6Nmzp7F161bjk08+Mby9vY3333/frFm7dq3h7u5uJCcnG9u3bzeGDh1qeHh4GN9//71Z8+abbxr+/v7GggULjM2bNxudO3c2IiMjjVOnTpXnZV41Pv/8c6N3797G0qVLjZ9//tn49NNPjeDgYGPQoEFmDXPj2vieVD5iY2ON1NRUY+vWrcamTZuMTp06GbVr1zaOHz9u1vTv398IDw83li9fbmzcuNG48847jZYtW5r7nfVzyJkITdeggoIC47rrrjP+/e9/n7dm8eLFhpubm5GZmWmOvffee4afn5+Rl5dnGIZhPP/888Ytt9zi8Li//e1vRmxsrLl9xx13GAkJCeZ2YWGhERYWZowaNcpZl1NpLV682GjQoIGxbdu2EqFp0qRJRmBgoDkXhmEY//znP4369eub2w8//LARFxfncMwWLVoYTz31lGEYhlFUVGSEhoYab731lrk/JyfHsNvtxieffHKFrqrySU5ONiIjI81t5sa18T2pYmRnZxuSjNWrVxuG8effZw8PD2Pu3LlmzY4dOwxJRnp6umEYzvs55Ey8PHcN+vbbb/Xrr7/Kzc1Nt912m2rVqqWOHTtq69atZk16eroaN27s8GnosbGxys3N1bZt28ya6Ohoh2PHxsYqPT1dkpSfn6+MjAyHGjc3N0VHR5s1KF1WVpb69u2rjz76SD4+PiX2p6en6+6775anp6c5Fhsbq507d+rIkSNmzYXmZ/fu3crMzHSo8ff3V4sWLZifS3D06FEFBQWZ28yN6+J7UsU5evSoJJlfKxkZGSooKHCYiwYNGqh27drmXDjj55CzEZquQb/88oskafjw4Ro6dKgWLlyowMBAtW3bVocPH5YkZWZmlvj1McXbmZmZF6zJzc3VqVOn9Pvvv6uwsLDUmuJjoCTDMNS7d2/1799fzZs3L7Xmcubn7P1nP660GlzYrl27NGHCBD311FPmGHPjuvieVDGKioqUlJSku+66S40a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",
"text/plain": [
"