{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/kasparvonbeelen/ghi_python/main?labpath=8_-_Data_Exploration_with_Pandas_I.ipynb)\n", "\n", "# Lecture 8: Exploring Tabular Data\n", "\n", "## Data Science for Historians (with Python)\n", "## A Gentle Introduction to Working with Data in Python\n", "\n", "### Created by Kaspar Beelen and Luke Blaxill\n", "\n", "### For the German Historical Institute, London\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.0 Overview\n", "\n", "In this notebook, we have a closer look at how to work with metadata. Using an example taken from the British Library Catalogue, this notebook demonstrates how to work with tabular data in a programmatic way using the Python library Pandas. \n", "\n", "More precisely, this lecture covers how to:\n", "\n", "- load a .CSV file as a Pandas data frame\n", "- select rows in a data frame\n", "- manipulate values in a data frame\n", "- sort data frames by column\n", "- make simple plots\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.1 Introduction\n", "\n", "In this lecture we turn to working with (semi-)structured data. \n", "\n", "We referred to text as 'unstructured' because it Python initially reads the document as sequence of characters. Most of our effort went to wrangling 'raw' text to more meaningful representations, by for example detecting and counting words.\n", "\n", "In the coming lectures, we will insepct tabular or structured data. Tabular data consists of **rows** and **columns**. The rows represent individual **records**, which can be basically anything, a book, a measurement, a person... The columns are the **atributes** of these records, they capture the **features** of each observation. \n", "\n", "Spreadsheets are common format for tabular data, documents which you can open and edit with programs such as Microsoft Excel.\n", "\n", "Without further ado, let's look at a concrete example: structured metadata from the British Library [catalogue](https://www.bl.uk/collection-metadata/metadata-services)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.2 CSV Data: Metadata on the British Library Books Corpus\n", "\n", "In the notebook, we will have a closer look at the [British Library Book corpus](https://www.bl.uk/collection-guides/digitised-printed-books) (BLB). This corpus contains around 60.000 books dating primarily from the 19th century. Its contents are freely accessible and have proved a rich resource for previous and ongoing research projects. \n", "\n", "One problem with this corpus, however, is its composition: while it is large, it remains unclear which types of content have been selected. The criteria remain for inclusion somewhat of a mystery and understanding the contours of the corpus is a non-trivial task that requires additional research at the level of corpus metadata.\n", "\n", "We focus therefore on exploring the metadata of this collection that is available as a CSV file. In this notebook, we show you how to explore the BLB metadata and get a better grip on the composition and contours of a large corpus. \n", "\n", "The data is available by following this link: `https://bl.iro.bl.uk/downloads/e1be1324-8b1a-4712-96a7-783ac209ddef?locale=en`. We first inspect the tabular format, and later on, have a more detailed exploration of data frames as a data structure.\n", "\n", "In the code below we use the `requests` library to download the data and save it in the `data` variable. We then print the first 400 characters." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import requests # requests library\n", "link = 'https://bl.iro.bl.uk/downloads/e1be1324-8b1a-4712-96a7-783ac209ddef?locale=en' # define location of data with url\n", "data = requests.get(link).text # get text" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'BL record ID,Type of resource,Name,Dates associated with name,Type of name,Role,All names,Title,Variant titles,Series title,Number within series,Country of publication,Place of publication,Publisher,Date of publication,Edition,Physical description,Dewey classification,BL shelfmark,Topics,Genre,Languages,Notes,BL record ID for physical resource\\n014602826,Monograph,\"Yearsley, Ann\",1753-1806,person,,'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data[:400]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you notice, these data are just text: i.e. the metadata is initially just a string. We can confirm this by printing the data `type`." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But, ho, wait. Didn't you tell us previously we'd be working with **structured** data? Yes, but let's have a look at the data in its 'raw' format first. \n", "\n", "What we printed in the cell above are the column names. You can observe how each name is separated by a comma (`,`). Also, spot the return character `\\n` which marks the end of a row. \n", "\n", "While our data is, initially, just a text file, you notice that the BLB metadata has an implicit structure, determined by comma's (cell boundaries) and hard returns (row boundaries). This format is commonly referred to as CSV, i.e. 'Comma Separated Values'. You will encounter this format regularly when working with data in the Digital Humanities. \n", "\n", "The first row of a CSV file contain usually the column headers which provide semantic information about the content of a column or, put differently, the attributes of each record. \n", "\n", "The BL books data contains the following columns:\n", "\n", "```\n", "BL record ID,Type of resource,Name,Dates associated with name,Type of name,Role,All names,Title,Variant titles,Series title,Number within series,Country of publication,Place of publication,Publisher,Date of publication,Edition,Physical description,Dewey classification,BL shelfmark,Topics,Genre,Languages,Notes,BL record ID for physical resource\n", "```\n", "\n", "The first record looks as follow:\n", "\n", "```\n", "014602826,Monograph,\"Yearsley, Ann\",1753-1806,person,,\"More, Hannah, 1745-1833 [person] ; Yearsley, Ann, 1753-1806 [person]\",Poems on several occasions [With a prefatory letter by Hannah More.],,,,England,London,,1786,Fourth edition MANUSCRIPT note,,,Digital Store 11644.d.32,,,English,,003996603\n", "```\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example, the first column (`BL record ID`) captures the identifier of a record. The identifier for the first record is `014602826`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.3 Exploring CSV files as Pandas DataFrames" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "While you could write a script to 'parse' these data, i.e. make the comma-separative structure explicit—remember `text.split(',')`?—there exist quite some tools to help you explore and analyse tabular CSV data. \n", "\n", "In this course, we will be working with Pandas, a popular Python library that covers many data science functionalities in Python.\n", "\n", "Below we import Pandas using the `pd` abbreviation. This is just for convenience, to save us typing characters. If we want to call any tools from this library we just have to prefix it `pd` instead of `pandas`" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can read the CSV file by providing the link to the online document to the `pd.read_csv` function." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv(\n", " \"https://bl.iro.bl.uk/downloads/e1be1324-8b1a-4712-96a7-783ac209ddef?locale=en\",\n", " index_col='BL record ID'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`read_csv()` takes a string as an argument. This string can either represent a path (e.g. the location of a file on your local hard drive) or a URL (e.g. a link to an online repository). In our case, we provide the URL as an argument. We added one more name argument `index_col` where we specified the values we want use an index for our rows.\n", "\n", "We save the output of this function call in a variable with the name `df` (short for data frame). The function returns a Pandas `DataFrame` object." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pandas.core.frame.DataFrame" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A dataframe consists of rows and columns. The `.shape` attribute gives you the dimensionality of the data frame, i.e. the number of rows and columns." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(52695, 23)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can observe, the BLB books corpus contains 52695 records. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To inspect the column names, print the `.columns` attribute attached to the DataFrame object `df`. This returns the metadata attributes present in the CSV file." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['Type of resource', 'Name', 'Dates associated with name',\n", " 'Type of name', 'Role', 'All names', 'Title', 'Variant titles',\n", " 'Series title', 'Number within series', 'Country of publication',\n", " 'Place of publication', 'Publisher', 'Date of publication', 'Edition',\n", " 'Physical description', 'Dewey classification', 'BL shelfmark',\n", " 'Topics', 'Genre', 'Languages', 'Notes',\n", " 'BL record ID for physical resource'],\n", " dtype='object')" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, we have rich and detailed metadata on each book in the BLB collection: dates, author names, genre etc." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use the `.head()` method to print the first rows. The code below prints the first three rows." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Type of resourceNameDates associated with nameType of nameRoleAll namesTitleVariant titlesSeries titleNumber within series...Date of publicationEditionPhysical descriptionDewey classificationBL shelfmarkTopicsGenreLanguagesNotesBL record ID for physical resource
BL record ID
14602826MonographYearsley, Ann1753-1806personNaNMore, Hannah, 1745-1833 [person] ; Yearsley, A...Poems on several occasions [With a prefatory l...NaNNaNNaN...1786Fourth edition MANUSCRIPT noteNaNNaNDigital Store 11644.d.32NaNNaNEnglishNaN3996603
14602830MonographA, T.NaNpersonNaNOldham, John, 1653-1683 [person] ; A, T. [person]A Satyr against Vertue. (A poem: supposed to b...NaNNaNNaN...1679NaN15 pages (4°)NaNDigital Store 11602.ee.10. (2.)NaNNaNEnglishNaN1143
14602831MonographNaNNaNNaNNaNNaNThe Aeronaut, a poem; founded almost entirely,...NaNNaNNaN...1816NaN17 pages (8°)NaNDigital Store 992.i.12. (3.)Dublin (Ireland)NaNEnglishNaN22782
\n", "

3 rows × 23 columns

\n", "
" ], "text/plain": [ " Type of resource Name Dates associated with name \\\n", "BL record ID \n", "14602826 Monograph Yearsley, Ann 1753-1806 \n", "14602830 Monograph A, T. NaN \n", "14602831 Monograph NaN NaN \n", "\n", " Type of name Role \\\n", "BL record ID \n", "14602826 person NaN \n", "14602830 person NaN \n", "14602831 NaN NaN \n", "\n", " All names \\\n", "BL record ID \n", "14602826 More, Hannah, 1745-1833 [person] ; Yearsley, A... \n", "14602830 Oldham, John, 1653-1683 [person] ; A, T. [person] \n", "14602831 NaN \n", "\n", " Title \\\n", "BL record ID \n", "14602826 Poems on several occasions [With a prefatory l... \n", "14602830 A Satyr against Vertue. (A poem: supposed to b... \n", "14602831 The Aeronaut, a poem; founded almost entirely,... \n", "\n", " Variant titles Series title Number within series ... \\\n", "BL record ID ... \n", "14602826 NaN NaN NaN ... \n", "14602830 NaN NaN NaN ... \n", "14602831 NaN NaN NaN ... \n", "\n", " Date of publication Edition \\\n", "BL record ID \n", "14602826 1786 Fourth edition MANUSCRIPT note \n", "14602830 1679 NaN \n", "14602831 1816 NaN \n", "\n", " Physical description Dewey classification \\\n", "BL record ID \n", "14602826 NaN NaN \n", "14602830 15 pages (4°) NaN \n", "14602831 17 pages (8°) NaN \n", "\n", " BL shelfmark Topics Genre \\\n", "BL record ID \n", "14602826 Digital Store 11644.d.32 NaN NaN \n", "14602830 Digital Store 11602.ee.10. (2.) NaN NaN \n", "14602831 Digital Store 992.i.12. (3.) Dublin (Ireland) NaN \n", "\n", " Languages Notes BL record ID for physical resource \n", "BL record ID \n", "14602826 English NaN 3996603 \n", "14602830 English NaN 1143 \n", "14602831 English NaN 22782 \n", "\n", "[3 rows x 23 columns]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may notice the many `NaN` values in the header of the data frame. `NaN` stands for 'not a value' and indicates that information is missing: we don't have information on 'Genre' for the books with id '14602826'.\n", "\n", "To quickly get an estimate of the completeness of our data, call the `info()` function." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Int64Index: 52695 entries, 14602826 to 16289062\n", "Data columns (total 23 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 Type of resource 52695 non-null object\n", " 1 Name 47552 non-null object\n", " 2 Dates associated with name 10825 non-null object\n", " 3 Type of name 47552 non-null object\n", " 4 Role 1680 non-null object\n", " 5 All names 49633 non-null object\n", " 6 Title 52695 non-null object\n", " 7 Variant titles 5867 non-null object\n", " 8 Series title 260 non-null object\n", " 9 Number within series 111 non-null object\n", " 10 Country of publication 36460 non-null object\n", " 11 Place of publication 51923 non-null object\n", " 12 Publisher 27487 non-null object\n", " 13 Date of publication 52517 non-null object\n", " 14 Edition 4198 non-null object\n", " 15 Physical description 39846 non-null object\n", " 16 Dewey classification 78 non-null object\n", " 17 BL shelfmark 52428 non-null object\n", " 18 Topics 3136 non-null object\n", " 19 Genre 1973 non-null object\n", " 20 Languages 52637 non-null object\n", " 21 Notes 6576 non-null object\n", " 22 BL record ID for physical resource 52695 non-null int64 \n", "dtypes: int64(1), object(22)\n", "memory usage: 9.6+ MB\n" ] } ], "source": [ "df.info()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As often when working with \"real\" data, completeness is an issue. For example, you can see that we have a title for each book (`52695 non-null`) while the majority of `Genre` column is empty (`1973 non-null`)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see `pd.read_csv` converted the 'raw' text to a tabular format, segmenting and properly identifying rows and columns.\n", "\n", "\n", "So far we used the Pandas functionalities—the `.head()` method and the `.shape` and `.columns` attributes attached to the data frame—to explore the structure of the metadata. \n", "\n", "But Pandas in the many tools for accessing, manipulating, and analysing tabular content. We first discuss how to access and retrieve content and then turn to manipulating information and producing basic analytics. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 8.3.1 Accessing Rows and Columns in DataFrames" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The most straightforward method for access is via the data frame index. In the code, above we specified that `BL record ID` should serve as the row index. This allows us the inspect a record related to a specific identifier. For example, if we want to inspect the book with identifier `14602826` we pass this identifier to `.loc`. \n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Type of resource Monograph\n", "Name NaN\n", "Dates associated with name NaN\n", "Type of name NaN\n", "Role NaN\n", "All names NaN\n", "Title The Aeronaut, a poem; founded almost entirely,...\n", "Variant titles NaN\n", "Series title NaN\n", "Number within series NaN\n", "Country of publication Ireland\n", "Place of publication Dublin\n", "Publisher Richard Milliken\n", "Date of publication 1816\n", "Edition NaN\n", "Physical description 17 pages (8°)\n", "Dewey classification NaN\n", "BL shelfmark Digital Store 992.i.12. (3.)\n", "Topics Dublin (Ireland)\n", "Genre NaN\n", "Languages English\n", "Notes NaN\n", "BL record ID for physical resource 22782\n", "Name: 14602831, dtype: object" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[14602831]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The syntax resembles accessing values by key in a Python dictionary: the item between square brackets is the key via which we retrieve the corresponding value. Similarly, you can read the line above as: retrieve the record (value) with the identifier (key) `14602831`. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also retrieve rows by their positional index using `.iloc()` (which is similar to the type indexing we used previously in Python lists). The code below returns the record at position 7 (or the 8th row)." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Type of resource Monograph\n", "Name NaN\n", "Dates associated with name NaN\n", "Type of name NaN\n", "Role NaN\n", "All names NaN\n", "Title Confessions of a Coquette, while staying at Sc...\n", "Variant titles NaN\n", "Series title NaN\n", "Number within series NaN\n", "Country of publication England\n", "Place of publication Scarborough\n", "Publisher E. T. W. Dennis\n", "Date of publication 1888\n", "Edition NaN\n", "Physical description 42 pages (8°)\n", "Dewey classification NaN\n", "BL shelfmark Digital Store 11602.ee.17. (8.)\n", "Topics NaN\n", "Genre NaN\n", "Languages English\n", "Notes NaN\n", "BL record ID for physical resource 156011\n", "Name: 14602836, dtype: object" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[7]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`.loc` and `iloc` allow slicing operations. The slice notation is similar to lists, where a colon separates the start and end positions of the slice we want. " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Type of resourceNameDates associated with nameType of nameRoleAll namesTitleVariant titlesSeries titleNumber within series...Date of publicationEditionPhysical descriptionDewey classificationBL shelfmarkTopicsGenreLanguagesNotesBL record ID for physical resource
BL record ID
14602831MonographNaNNaNNaNNaNNaNThe Aeronaut, a poem; founded almost entirely,...NaNNaNNaN...1816NaN17 pages (8°)NaNDigital Store 992.i.12. (3.)Dublin (Ireland)NaNEnglishNaN22782
14602832MonographAlbert, Prince Consort, consort of Victoria, Q...1819-1861personNaNPlimsoll, Joseph [person] ; Albert, Prince Con...The Prince Albert, a poem [By Joseph Plimsoll.]AppendixNaNNaN...1868NaN16 pages (8°)NaNDigital Store 11602.ee.17. (1.)NaNNaNEnglishNaN39775
14602833MonographAnslow, RobertNaNpersonNaNAnslow, Robert [person]The Defeat of the Spanish Armada, A.D. 1588. A...NaNNaNNaN...1888NaN40 pages (8°)NaNDigital Store 11602.ee.17. (7.)NaNNaNEnglishNaN92666
14602834MonographNaNNaNNaNNaNSwift, Jonathan, 1667-1745 [person]A Familiar Answer to a Familiar Letter [In ver...Appendix. I. Contemporary Satires, Eulogies, etcNaNNaN...1720NaN7 pages (4°)NaNDigital Store 11602.ee.10. (5.)NaNNaNEnglishNaN93359
14602835MonographNaNNaNNaNNaNNaNThe Irish Home Rule Bill. A poetical pamphlet,...NaNNaNNaN...1893NaN4 pages (8°)NaNDigital Store 11601.g.28. (3.)NaNNaNEnglishNaN150273
\n", "

5 rows × 23 columns

\n", "
" ], "text/plain": [ " Type of resource \\\n", "BL record ID \n", "14602831 Monograph \n", "14602832 Monograph \n", "14602833 Monograph \n", "14602834 Monograph \n", "14602835 Monograph \n", "\n", " Name \\\n", "BL record ID \n", "14602831 NaN \n", "14602832 Albert, Prince Consort, consort of Victoria, Q... \n", "14602833 Anslow, Robert \n", "14602834 NaN \n", "14602835 NaN \n", "\n", " Dates associated with name Type of name Role \\\n", "BL record ID \n", "14602831 NaN NaN NaN \n", "14602832 1819-1861 person NaN \n", "14602833 NaN person NaN \n", "14602834 NaN NaN NaN \n", "14602835 NaN NaN NaN \n", "\n", " All names \\\n", "BL record ID \n", "14602831 NaN \n", "14602832 Plimsoll, Joseph [person] ; Albert, Prince Con... \n", "14602833 Anslow, Robert [person] \n", "14602834 Swift, Jonathan, 1667-1745 [person] \n", "14602835 NaN \n", "\n", " Title \\\n", "BL record ID \n", "14602831 The Aeronaut, a poem; founded almost entirely,... \n", "14602832 The Prince Albert, a poem [By Joseph Plimsoll.] \n", "14602833 The Defeat of the Spanish Armada, A.D. 1588. A... \n", "14602834 A Familiar Answer to a Familiar Letter [In ver... \n", "14602835 The Irish Home Rule Bill. A poetical pamphlet,... \n", "\n", " Variant titles Series title \\\n", "BL record ID \n", "14602831 NaN NaN \n", "14602832 Appendix NaN \n", "14602833 NaN NaN \n", "14602834 Appendix. I. Contemporary Satires, Eulogies, etc NaN \n", "14602835 NaN NaN \n", "\n", " Number within series ... Date of publication Edition \\\n", "BL record ID ... \n", "14602831 NaN ... 1816 NaN \n", "14602832 NaN ... 1868 NaN \n", "14602833 NaN ... 1888 NaN \n", "14602834 NaN ... 1720 NaN \n", "14602835 NaN ... 1893 NaN \n", "\n", " Physical description Dewey classification \\\n", "BL record ID \n", "14602831 17 pages (8°) NaN \n", "14602832 16 pages (8°) NaN \n", "14602833 40 pages (8°) NaN \n", "14602834 7 pages (4°) NaN \n", "14602835 4 pages (8°) NaN \n", "\n", " BL shelfmark Topics Genre \\\n", "BL record ID \n", "14602831 Digital Store 992.i.12. (3.) Dublin (Ireland) NaN \n", "14602832 Digital Store 11602.ee.17. (1.) NaN NaN \n", "14602833 Digital Store 11602.ee.17. (7.) NaN NaN \n", "14602834 Digital Store 11602.ee.10. (5.) NaN NaN \n", "14602835 Digital Store 11601.g.28. (3.) NaN NaN \n", "\n", " Languages Notes BL record ID for physical resource \n", "BL record ID \n", "14602831 English NaN 22782 \n", "14602832 English NaN 39775 \n", "14602833 English NaN 92666 \n", "14602834 English NaN 93359 \n", "14602835 English NaN 150273 \n", "\n", "[5 rows x 23 columns]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[14602831:14602835] # get records with BL record ID 14602831 to 14602835" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Type of resourceNameDates associated with nameType of nameRoleAll namesTitleVariant titlesSeries titleNumber within series...Date of publicationEditionPhysical descriptionDewey classificationBL shelfmarkTopicsGenreLanguagesNotesBL record ID for physical resource
BL record ID
14603039MonographStanhope, H., pseudonym [i.e. William Bond?]NaNpersonNaNStanhope, H., pseudonym [i.e. William Bond?] [...The Patriot: an epistle [in verse] to ... Phil...NaNNaNNaN...1733NaN8 pages (folio)NaNDigital Store 11642.i.9. (2.)NaNNaNEnglishNaN3477622
14603040MonographNaNNaNNaNNaNNaNVae Victis. Duty, and other poemsNaNNaNNaN...1850NaNNaNNaNDigital Store 11645.g.45NaNPoetry or verseEnglishNaN3745155
14603041MonographWebber, ThomasNaNpersonNaNWebber, Thomas [person]Stockton: an historical, biographical and desc...NaNNaNNaN...1830NaN40 pages (8°)NaNDigital Store 11643.bbb.25. (4.)NaNNaNEnglishNaN3871500
14603042MonographWells, E. T.NaNpersonNaNWells, E. T. [person]A Few VersesNaNNaNNaN...1895NaN11 pages (8°)NaNDigital Store 11601.f.36. (5.)NaNNaNEnglishNaN3885435
14603043MonographWilson, J. GordonNaNpersonNaNWilson, J. Gordon [person]Descriptive Poem. The Death of ... F. Burnaby ...NaNNaNNaN...1885NaNNaNNaNDigital Store 11643.bbb.25. (9.)NaNNaNEnglishNaN3945042
\n", "

5 rows × 23 columns

\n", "
" ], "text/plain": [ " Type of resource Name \\\n", "BL record ID \n", "14603039 Monograph Stanhope, H., pseudonym [i.e. William Bond?] \n", "14603040 Monograph NaN \n", "14603041 Monograph Webber, Thomas \n", "14603042 Monograph Wells, E. T. \n", "14603043 Monograph Wilson, J. Gordon \n", "\n", " Dates associated with name Type of name Role \\\n", "BL record ID \n", "14603039 NaN person NaN \n", "14603040 NaN NaN NaN \n", "14603041 NaN person NaN \n", "14603042 NaN person NaN \n", "14603043 NaN person NaN \n", "\n", " All names \\\n", "BL record ID \n", "14603039 Stanhope, H., pseudonym [i.e. William Bond?] [... \n", "14603040 NaN \n", "14603041 Webber, Thomas [person] \n", "14603042 Wells, E. T. [person] \n", "14603043 Wilson, J. Gordon [person] \n", "\n", " Title \\\n", "BL record ID \n", "14603039 The Patriot: an epistle [in verse] to ... Phil... \n", "14603040 Vae Victis. Duty, and other poems \n", "14603041 Stockton: an historical, biographical and desc... \n", "14603042 A Few Verses \n", "14603043 Descriptive Poem. The Death of ... F. Burnaby ... \n", "\n", " Variant titles Series title Number within series ... \\\n", "BL record ID ... \n", "14603039 NaN NaN NaN ... \n", "14603040 NaN NaN NaN ... \n", "14603041 NaN NaN NaN ... \n", "14603042 NaN NaN NaN ... \n", "14603043 NaN NaN NaN ... \n", "\n", " Date of publication Edition Physical description \\\n", "BL record ID \n", "14603039 1733 NaN 8 pages (folio) \n", "14603040 1850 NaN NaN \n", "14603041 1830 NaN 40 pages (8°) \n", "14603042 1895 NaN 11 pages (8°) \n", "14603043 1885 NaN NaN \n", "\n", " Dewey classification BL shelfmark Topics \\\n", "BL record ID \n", "14603039 NaN Digital Store 11642.i.9. (2.) NaN \n", "14603040 NaN Digital Store 11645.g.45 NaN \n", "14603041 NaN Digital Store 11643.bbb.25. (4.) NaN \n", "14603042 NaN Digital Store 11601.f.36. (5.) NaN \n", "14603043 NaN Digital Store 11643.bbb.25. (9.) NaN \n", "\n", " Genre Languages Notes \\\n", "BL record ID \n", "14603039 NaN English NaN \n", "14603040 Poetry or verse English NaN \n", "14603041 NaN English NaN \n", "14603042 NaN English NaN \n", "14603043 NaN English NaN \n", "\n", " BL record ID for physical resource \n", "BL record ID \n", "14603039 3477622 \n", "14603040 3745155 \n", "14603041 3871500 \n", "14603042 3885435 \n", "14603043 3945042 \n", "\n", "[5 rows x 23 columns]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[200:205] # get records at position 200 to 205" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So far, we accessed the content in the dataframe by specifying the rows we wanted to retrieve. But the Pandas data frames enable you to retrieve items by column, for example, the line of code below that returns the date of publication for each book in our corpus (column with name `\"'Date of publication'\"`)." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BL record ID\n", "14602826 1786\n", "14602830 1679\n", "14602831 1816\n", "14602832 1868\n", "14602833 1888\n", " ... \n", "16289058 NaN\n", "16289059 NaN\n", "16289060 1913\n", "16289061 1924\n", "16289062 1919\n", "Name: Date of publication, Length: 52695, dtype: object" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Date of publication']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that columns belong to a different data type, namely `Series`. While a DataFrame always has two dimensions (rows and columns) a Series object only has one." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pandas.core.series.Series" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df['Date of publication'])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(52695,)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Date of publication'].shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Returning the columns itself:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BL record ID\n", "14602826 1786\n", "14602830 1679\n", "14602831 1816\n", "14602832 1868\n", "14602833 1888\n", " ... \n", "16289058 NaN\n", "16289059 NaN\n", "16289060 1913\n", "16289061 1924\n", "16289062 1919\n", "Name: Date of publication, Length: 52695, dtype: object" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Date of publication']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The output shows the BL record identifier and the corresponding year of publication. Please notice the following:\n", "- Firstly, again some records have NaN (not a number) as date. This points to missing data, i.e. the book lacks a date of publication which can happen for many reasons. In Pandas the NaN is an instance of the float class. Run the code below to see if for yourself." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nan\n" ] } ], "source": [ "n = df.loc[16289059,'Date of publication']\n", "print(n)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Secondly, each column belongs to a specific data type or `dtype`. In this case, the date of publication columns has `object` as its data type, which often indicates that the column contains information of different types or strings. This may come as a surprise: we would expect dates or integers to appear in this case. If we look closer at the row with identifier `16289061` we observe that the year is a string. `Date of Publication` contains a mixture of string and float (`NaN`) objects. Later in this tutorial, we will show how to convert this column to an integer expressing the year of publication, which we can subsequently use to plot timelines." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1924 \n" ] } ], "source": [ "n = df.loc[16289061,'Date of publication']\n", "print(n,type(n))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To select more than one column, for example Date of Publication and Genre, you have to pass a **list** with column names. The first line of code below will fail, but the second one will work (notice the double square brackets in the second statement)." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "ename": "KeyError", "evalue": "('Date of publication', 'Genre')", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 3360\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3361\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3362\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;31mKeyError\u001b[0m: ('Date of publication', 'Genre')", "\nThe above exception was the direct cause of the following exception:\n", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/2_/fcdvqwzs6j75cfr97nggzfn499sjqf/T/ipykernel_39483/2653721281.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Date of publication'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'Genre'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m# this will not work\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 3453\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnlevels\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3454\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3455\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3456\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3457\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 3361\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3362\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3363\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3364\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3365\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhasnans\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mKeyError\u001b[0m: ('Date of publication', 'Genre')" ] } ], "source": [ "df['Date of publication','Genre'] # this will not work " ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Date of publicationGenre
BL record ID
146028261786NaN
146028301679NaN
146028311816NaN
146028321868NaN
146028331888NaN
.........
16289058NaNNaN
16289059NaNNaN
162890601913NaN
162890611924NaN
162890621919NaN
\n", "

52695 rows × 2 columns

\n", "
" ], "text/plain": [ " Date of publication Genre\n", "BL record ID \n", "14602826 1786 NaN\n", "14602830 1679 NaN\n", "14602831 1816 NaN\n", "14602832 1868 NaN\n", "14602833 1888 NaN\n", "... ... ...\n", "16289058 NaN NaN\n", "16289059 NaN NaN\n", "16289060 1913 NaN\n", "16289061 1924 NaN\n", "16289062 1919 NaN\n", "\n", "[52695 rows x 2 columns]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[['Date of publication','Genre']] # this works!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas provides valuable tools for exploring the values of a specific column. `.value_counts()` will return the frequency of each unique value in the columns. For example, we can apply this method to the Genre column, to assess which genres appear in the metadata and how often. Notice that it excludes a count of `NaN` values." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Poetry or verse 1002\n", "Drama 461\n", "Drama ; Poetry or verse 151\n", "Travel 77\n", "Periodical 39\n", " ... \n", "Drama ; Early works to 1800 ; Libretto 1\n", "Census data ; Gazetteer 1\n", "History 1\n", "Translations into Latin 1\n", "Biography ; Source 1\n", "Name: Genre, Length: 64, dtype: int64" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Genre'].value_counts()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `.unique()` methods show the **set** of the values in a columns (i.e. each unique value). This helps us to understand and explore range of values in a column. For example, below we can inspect all the unique genres present in the BL books corpus." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([nan, 'Song', 'Poetry or verse', 'Music', 'Drama ; Poetry or verse',\n", " 'Drama', 'Periodical', 'Poetry or verse ; Song', 'Biography',\n", " 'Libretto', 'Drama ; Essay ; Poetry or verse', 'Diary',\n", " 'Pictorial work', 'Drama ; Libretto', 'Travel', 'Census data',\n", " 'Diary ; Travel', 'Lecture', 'Gazetteer', 'Guidebook',\n", " 'Compendium or compilation', 'Correspondence', 'Directory',\n", " 'Essay', 'Fiction', 'Review', 'Drawing', 'Drama ; Drawing',\n", " 'Novel', 'Ephemeris', 'Early works to 1800',\n", " 'Correspondence ; Travel', 'Drama ; Essay', \"Children's fiction\",\n", " 'Illustration', 'Correspondence ; Diary',\n", " 'Translations into Italian',\n", " 'Translations from English ; Translations into Russian', 'Hymnal',\n", " 'Calendar ; Poetry or verse',\n", " 'Drama ; Early works to 1800 ; Libretto', 'Handbook or manual',\n", " 'Atlas', 'Census data ; Gazetteer', 'History',\n", " 'Translations into Latin', 'Periodical ; Poetry or verse',\n", " 'Engraving ; Illustration ; Plan or view', 'Dictionary',\n", " 'Concordance', 'Short story', 'Guidebook ; Travel', 'Textbook',\n", " 'Register', 'Source', 'Statistics', 'Encyclopaedia', 'Lithograph',\n", " 'Biography ; Diary ; Personal narrative',\n", " 'Diary ; Personal narrative', 'Lithograph ; Plan or view',\n", " 'Handbook or manual ; Periodical', 'Humour or satire',\n", " 'Bibliography', 'Biography ; Source'], dtype=object)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Genre'].unique()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can then use this information to select specific rows by Genre, e.g. return all books categorized as 'Travel' literature. To accomplish this, we need to construct a **mask**: an array of boolean (True, False) values that express which row matches a certain condition (i.e. Gender is equal to the string 'Travel'). Let's explore this with a toy example.\n", "\n", "First, we create a small, data frame, which only records the date of publication and genre." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Date of PublicationGenre
01944Travel
11943Periodical
21946Travel
31947Biography
\n", "
" ], "text/plain": [ " Date of Publication Genre\n", "0 1944 Travel\n", "1 1943 Periodical\n", "2 1946 Travel\n", "3 1947 Biography" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_toy = pd.DataFrame([[1944,'Travel'],\n", " [1943,'Periodical'],\n", " [1946,'Travel'],\n", " [1947,'Biography']], columns= ['Date of Publication','Genre'])\n", "df_toy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we create a mask using the `==` (is equal to) operator. In this case, we retrieve rows where the value in the Genre column is equal to `Travel`. This operation returns an array (more precisely a Pandas Series object) of boolean values: True when the recorded genre of a book matches the string `\"Travel\"`, False otherwise." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 True\n", "1 False\n", "2 True\n", "3 False\n", "Name: Genre, dtype: bool" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_toy['Genre'] == \"Travel\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can save this mask in the `mask` variable (notice the difference between `=`, value assignment, and `==` \"equal to\" operator )" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 True\n", "1 False\n", "2 True\n", "3 False\n", "Name: Genre, dtype: bool" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mask = df_toy['Genre'] == \"Travel\"\n", "mask" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We pass `mask` to `.loc[]`, which selects the rows in the toy dataframe that contain travel literature." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Date of PublicationGenre
01944Travel
21946Travel
\n", "
" ], "text/plain": [ " Date of Publication Genre\n", "0 1944 Travel\n", "2 1946 Travel" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_toy.loc[mask]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Masking will return later on this course. For now it suffices to say that Pandas provides some useful functions for selecting subsets of a of dataframe. `.isin()` for example, is useful in scenarios where one wants to find multipe genres, for example `'Travel'` and `'Biography'`. This method takes a list of values as argument, and will return rows whose values appear in this list." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 True\n", "1 False\n", "2 True\n", "3 True\n", "Name: Genre, dtype: bool" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mask = df_toy['Genre'].isin([\"Travel\",\"Biography\"])\n", "mask" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Date of PublicationGenre
01944Travel
21946Travel
31947Biography
\n", "
" ], "text/plain": [ " Date of Publication Genre\n", "0 1944 Travel\n", "2 1946 Travel\n", "3 1947 Biography" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_toy[mask]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course, we could have repeatedly used the `==` operator and combined the results. However, `.isin()` provides a more elegant solution.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is one more symbol to use in this context: the tilde or `~` which serves as a negation. In the example below, we obtain all rows **except** those having 'Travel' as their Genre." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Date of PublicationGenre
11943Periodical
31947Biography
\n", "
" ], "text/plain": [ " Date of Publication Genre\n", "1 1943 Periodical\n", "3 1947 Biography" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mask = df_toy['Genre'].isin([\"Travel\"])\n", "df_toy[~mask]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's return to our main case study, the BLB corpus. The statements below demonstrate how masking enables you to explore these data by Genre. \n", "\n", "Note how we save the subsection of the original dataframe in a new variable `travel`." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Type of resourceNameDates associated with nameType of nameRoleAll namesTitleVariant titlesSeries titleNumber within series...Date of publicationEditionPhysical descriptionDewey classificationBL shelfmarkTopicsGenreLanguagesNotesBL record ID for physical resource
BL record ID
14750869MonographGrindlay & CoNaNorganisationNaNGrindlay & Co [organisation]Grindlay and Co.'s Overland Circular. Hints fo...NaNNaNNaN...1854Third editionNaNNaNDigital Store 1298.h.25. (3.)IndiaTravelEnglishNaN1517704
14756377MonographStocqueler, J. H. (Joachim Hayward)1800-1885personNaNStocqueler, J. H. (Joachim Hayward), 1800-1885...The Overland Companion: being a guide for the ...NaNNaNNaN...1850NaN(12°)NaNDigital Store 1298.h.14Asia--Description and travel ; India ; EgyptTravelEnglishNaN3510639
14804046MonographAnnesley, George, Earl of MountnorrisNaNpersonNaNAnnesley, George, Earl of Mountnorris [person]...Voyages and Travels to India, Ceylon, the Red ...NaNNaNNaN...1809NaN3 volumes (4°)NaNDigital Store 10058.l.13India ; Sri Lanka ; EgyptTravelEnglishNaN91083
14804297MonographAtkinson, Thomas WitlamNaNpersonNaNAtkinson, Thomas Witlam [person]Travels in the Regions of the Upper and Lower ...NaNNaNNaN...1860NaNxiii, 570 pages (8°)NaNDigital Store 010058.ff.2China ; India ; RussiaTravelEnglishNaN136225
14804834MonographBaynes, C. R. (Charles Robert)NaNpersonNaNBaynes, C. R. (Charles Robert) [person]Notes and Reflections, during a ramble in the ...NaNNaNNaN...1843NaNviii, 275 pages (12°)NaNDigital Store 1425.d.7IndiaTravelEnglishNaN236176
..................................................................
14839906MonographElwood, Anne Katharine, MrsNaNpersonNaNElwood, Anne Katharine, Mrs [person]Narrative of a journey overland from England, ...NaNNaNNaN...1830NaN2 volumes (8°)NaNDigital Store 1046.d.6-7Voyages and travels ; India ; India--Descripti...TravelEnglishNaN1063966
14848081MonographStocqueler, J. H. (Joachim Hayward)1800-1885personNaNStocqueler, J. H. (Joachim Hayward), 1800-1885...The Hand-Book of India, a guide to the strange...NaNNaNNaN...1845Second edition(12°)NaNDigital Store 1298.h.8India ; India--GuidebooksTravelEnglishNaN3510627
14871557MonographDemidov, Anatoly Nikolaevich, Prince di San Do...NaNpersonNaNDemidov, Anatoly Nikolaevich, Prince di San Do...Esquisses d'un voyage dans la Russie méridiona...NaNNaNNaN...1838NaN102 pages (8°)NaNDigital Store 10291.e.2Crimea (Ukraine)--19th century--Description an...TravelFrenchNaN905050
14872822MonographSementovsky, NikolaiNaNpersonNaNSementovsky, Nikolai [person]Кіевъ, его святиня, древности, достопамятности...NaNNaNNaN...1864NaNNaNNaNDigital Store 10291.e.21Kiev (Ukraine)--Description and travelTravelRussianNaN3334914
15743152MonographWynne, Arthur BeevorNaNpersonNaNWynne, Arthur Beevor [person]On the connexion between Travelled Blocks in t...NaNNaNNaN...1881NaN3 pages (8°)NaNDigital Store 7106.f.14. (1.)Geology ; IndiaTravelEnglishNaN3990134
\n", "

77 rows × 23 columns

\n", "
" ], "text/plain": [ " Type of resource \\\n", "BL record ID \n", "14750869 Monograph \n", "14756377 Monograph \n", "14804046 Monograph \n", "14804297 Monograph \n", "14804834 Monograph \n", "... ... \n", "14839906 Monograph \n", "14848081 Monograph \n", "14871557 Monograph \n", "14872822 Monograph \n", "15743152 Monograph \n", "\n", " Name \\\n", "BL record ID \n", "14750869 Grindlay & Co \n", "14756377 Stocqueler, J. H. (Joachim Hayward) \n", "14804046 Annesley, George, Earl of Mountnorris \n", "14804297 Atkinson, Thomas Witlam \n", "14804834 Baynes, C. R. (Charles Robert) \n", "... ... \n", "14839906 Elwood, Anne Katharine, Mrs \n", "14848081 Stocqueler, J. H. (Joachim Hayward) \n", "14871557 Demidov, Anatoly Nikolaevich, Prince di San Do... \n", "14872822 Sementovsky, Nikolai \n", "15743152 Wynne, Arthur Beevor \n", "\n", " Dates associated with name Type of name Role \\\n", "BL record ID \n", "14750869 NaN organisation NaN \n", "14756377 1800-1885 person NaN \n", "14804046 NaN person NaN \n", "14804297 NaN person NaN \n", "14804834 NaN person NaN \n", "... ... ... ... \n", "14839906 NaN person NaN \n", "14848081 1800-1885 person NaN \n", "14871557 NaN person NaN \n", "14872822 NaN person NaN \n", "15743152 NaN person NaN \n", "\n", " All names \\\n", "BL record ID \n", "14750869 Grindlay & Co [organisation] \n", "14756377 Stocqueler, J. H. (Joachim Hayward), 1800-1885... \n", "14804046 Annesley, George, Earl of Mountnorris [person]... \n", "14804297 Atkinson, Thomas Witlam [person] \n", "14804834 Baynes, C. R. (Charles Robert) [person] \n", "... ... \n", "14839906 Elwood, Anne Katharine, Mrs [person] \n", "14848081 Stocqueler, J. H. (Joachim Hayward), 1800-1885... \n", "14871557 Demidov, Anatoly Nikolaevich, Prince di San Do... \n", "14872822 Sementovsky, Nikolai [person] \n", "15743152 Wynne, Arthur Beevor [person] \n", "\n", " Title \\\n", "BL record ID \n", "14750869 Grindlay and Co.'s Overland Circular. Hints fo... \n", "14756377 The Overland Companion: being a guide for the ... \n", "14804046 Voyages and Travels to India, Ceylon, the Red ... \n", "14804297 Travels in the Regions of the Upper and Lower ... \n", "14804834 Notes and Reflections, during a ramble in the ... \n", "... ... \n", "14839906 Narrative of a journey overland from England, ... \n", "14848081 The Hand-Book of India, a guide to the strange... \n", "14871557 Esquisses d'un voyage dans la Russie méridiona... \n", "14872822 Кіевъ, его святиня, древности, достопамятности... \n", "15743152 On the connexion between Travelled Blocks in t... \n", "\n", " Variant titles Series title Number within series ... \\\n", "BL record ID ... \n", "14750869 NaN NaN NaN ... \n", "14756377 NaN NaN NaN ... \n", "14804046 NaN NaN NaN ... \n", "14804297 NaN NaN NaN ... \n", "14804834 NaN NaN NaN ... \n", "... ... ... ... ... \n", "14839906 NaN NaN NaN ... \n", "14848081 NaN NaN NaN ... \n", "14871557 NaN NaN NaN ... \n", "14872822 NaN NaN NaN ... \n", "15743152 NaN NaN NaN ... \n", "\n", " Date of publication Edition Physical description \\\n", "BL record ID \n", "14750869 1854 Third edition NaN \n", "14756377 1850 NaN (12°) \n", "14804046 1809 NaN 3 volumes (4°) \n", "14804297 1860 NaN xiii, 570 pages (8°) \n", "14804834 1843 NaN viii, 275 pages (12°) \n", "... ... ... ... \n", "14839906 1830 NaN 2 volumes (8°) \n", "14848081 1845 Second edition (12°) \n", "14871557 1838 NaN 102 pages (8°) \n", "14872822 1864 NaN NaN \n", "15743152 1881 NaN 3 pages (8°) \n", "\n", " Dewey classification BL shelfmark \\\n", "BL record ID \n", "14750869 NaN Digital Store 1298.h.25. (3.) \n", "14756377 NaN Digital Store 1298.h.14 \n", "14804046 NaN Digital Store 10058.l.13 \n", "14804297 NaN Digital Store 010058.ff.2 \n", "14804834 NaN Digital Store 1425.d.7 \n", "... ... ... \n", "14839906 NaN Digital Store 1046.d.6-7 \n", "14848081 NaN Digital Store 1298.h.8 \n", "14871557 NaN Digital Store 10291.e.2 \n", "14872822 NaN Digital Store 10291.e.21 \n", "15743152 NaN Digital Store 7106.f.14. (1.) \n", "\n", " Topics Genre \\\n", "BL record ID \n", "14750869 India Travel \n", "14756377 Asia--Description and travel ; India ; Egypt Travel \n", "14804046 India ; Sri Lanka ; Egypt Travel \n", "14804297 China ; India ; Russia Travel \n", "14804834 India Travel \n", "... ... ... \n", "14839906 Voyages and travels ; India ; India--Descripti... Travel \n", "14848081 India ; India--Guidebooks Travel \n", "14871557 Crimea (Ukraine)--19th century--Description an... Travel \n", "14872822 Kiev (Ukraine)--Description and travel Travel \n", "15743152 Geology ; India Travel \n", "\n", " Languages Notes BL record ID for physical resource \n", "BL record ID \n", "14750869 English NaN 1517704 \n", "14756377 English NaN 3510639 \n", "14804046 English NaN 91083 \n", "14804297 English NaN 136225 \n", "14804834 English NaN 236176 \n", "... ... ... ... \n", "14839906 English NaN 1063966 \n", "14848081 English NaN 3510627 \n", "14871557 French NaN 905050 \n", "14872822 Russian NaN 3334914 \n", "15743152 English NaN 3990134 \n", "\n", "[77 rows x 23 columns]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mask = df['Genre'] == \"Travel\"\n", "travel = df[mask]\n", "travel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we can work on a subset of rows and inspect the number of travel books in the collection with their titles." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(77, 23)" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "travel.shape" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BL record ID\n", "14750869 Grindlay and Co.'s Overland Circular. Hints fo...\n", "14756377 The Overland Companion: being a guide for the ...\n", "14804046 Voyages and Travels to India, Ceylon, the Red ...\n", "14804297 Travels in the Regions of the Upper and Lower ...\n", "14804834 Notes and Reflections, during a ramble in the ...\n", " ... \n", "14839906 Narrative of a journey overland from England, ...\n", "14848081 The Hand-Book of India, a guide to the strange...\n", "14871557 Esquisses d'un voyage dans la Russie méridiona...\n", "14872822 Кіевъ, его святиня, древности, достопамятности...\n", "15743152 On the connexion between Travelled Blocks in t...\n", "Name: Title, Length: 77, dtype: object" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "travel['Title']" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Voyages and Travels to India, Ceylon, the Red Sea, Abyssinia, and Egypt. 1802, 1803, 1804, 1805 and 1806 [With plates by Henry Salt.]'" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "travel['Title'].iloc[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 8.3.2 Manipulating dataframes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have already covered quite some ground in this notebook. At this point, you should understand how to open and explore Pandas DataFrames. In what follows, we demonstrate how to change and manipulate information in a data frame. We focus on processing the dates of publication and convert the strings to integers that indicate the year of publication. This will help us later on with plotting and investigating trends over time.\n", "\n", "First, let us inspect the values in the column in more detail." ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['1786', '1679', '1816', '1868', '1888', '1720', '1893', '1815',\n", " '1848', '1889', '1710', '1886', '1887', '1896', '1688', '1899',\n", " '1791', '1805', '1691', '1818', '1897', '1858', '1890', '1814',\n", " '1882', '1885', '1840', '1894', '1809', '1875', '1819', '1774',\n", " '1898', '1769', '1856', '1857', '1775', '1773', '1776', '1866',\n", " '1799', '1841', '1828', '1765', '1807', '1845', '1872', '1823',\n", " '1759', '1768', '1780', '1806', '1705', '1821', '1800', '1734',\n", " '1767', '1817', '1792', '1892', '1801', '1756', '1824', '1762',\n", " '1793', '1770', '1690', '1761', '1785', '1810', '1764', '1757',\n", " '1797', '1689', '1883', '1884', '1766', '1833', '1798', '1803',\n", " '1891', '1820', '1750', '1850', '1777', '1842', '1813', '1830',\n", " '1787', '1853', '1733', '1895', '1879', '1742', '1754', '1812',\n", " '1861', '1796', '1825', '1746', '1832', '1755', '1852', '1871',\n", " '1795', '1790', '1788', '1741', '1709', '1789', '1880', '1782',\n", " '1715', '1827', '1829', '1727', '1772', '1802', '1752', '1837',\n", " '1836', '1834', '1732', '1847', '1863', '1694', '1804', '1783',\n", " '1822', '1649', '1651', '1670', '1663', '1839', '1704', '1835',\n", " '1838', '1859', '1843', '1778', '1855', '1851', '1779', '1849',\n", " '1707', '1722', '1831', '1862', '1878', '1708', '1865', '1676',\n", " '1695', '1684', '1844', '1681', '1869', '1747', '1860', '1717',\n", " '1811', '1874', '1718', '1826', '1706', '1662', '1744', '1794',\n", " '1846', '1652', '1771', '1728', '1808', '1714', '1716', '1703',\n", " '1881', '1745', '1641', '1730', '1700', '1736', '1661', '1696',\n", " '1784', '1739', '1738', '1635', '1737', '1713', '1686', '1623',\n", " '1877', '1697', '1682', '1760', '1616', nan, '1665', '1655',\n", " '1687', '1711', '1701', '1854', '1729', '1867', '1927', '1870',\n", " '1596', '1873', '1735', '1698', '1685', '1719', '1660', '1633',\n", " '1644', '1666', '1528', '1639', '1556', '1667', '1637', '1653',\n", " '1693', '1668', '1900', '1876', '1781', '1763', '1864', '1674',\n", " '1743', '1731', '1647', '1712', '1821-', '1672', '1751', '1917',\n", " '1726', '1724', '1680', '1758', '1678', '1749', '1702', '1753',\n", " '1748', '1723', '1725', '1721', '1886-', '1896-', '1909', '1874-',\n", " '1829-', '1918', '1830-', '1683', '1878-1879', '1872-1873',\n", " '1892-1925', '1905', '1936', '1692', '1922', '1640', '1631',\n", " '1650', '1634', '1625', '1648', '1906', '1671', '1849-1850',\n", " '1890-1891', '1914', '1957', '1904', '1837-1839', '1677', '1657',\n", " '1846-', '1902', '1658', '1612', '1846-1847', '1646', '1912',\n", " '1780-1790', '1605', '1630', '1675', '1908', '1599', '1656',\n", " '1636', '1606', '1659', '1673', '1699', '1669', '1861-1862',\n", " '1626', '1857-1863', '1876-1869', '1887-1878', '1819-',\n", " '1811-1817', '1615', '1592', '1540', '1886-1887', '1921', '1638',\n", " '1617', '1880-1989', '1809-1811', '1654', '1932', '1642', '1611',\n", " '1937', '1907', '1781-', '1607', '1629', '1664', '1643', '1924',\n", " '1632', '1618', '1584', '1916', '1910', '1903', '1622', '1602',\n", " '1613', '1898-1902', '1871-1872', '1882-1884', '1881-1886',\n", " '1808-', '1872-', '1795-', '1911', '1740', '1870-1883',\n", " '1894-1898', '1879-1885', '1940', '1834-', '1926', '1864-', '1610',\n", " '1859-1862', '1593', '1817-', '1843-', '1839-', '1838-', '1855-',\n", " '1876-', '1893-', '1802-', '1887-', '1822-', '1824-', '1844-1847',\n", " '1510', '1825-', '1628', '1925', '1608', '1917-', '1883-1884',\n", " '1866-', '1888-1894', '1853-', '1845-', '1858-', '1862-1863',\n", " '1913', '1901', '1938', '1885-1908', '1823-', '1949', '1923',\n", " '1915', '1805-', '1878-1885', '1939', '1886-1980', '1874-1888',\n", " '1811-1813', '1892-1912', '1851-1873', '1865-1869', '1811-1812',\n", " '1897-', '1829-1830', '1887-1889', '1882-1894', '1882-1893',\n", " '1974', '1893-1895', '1848-1849', '1871-', '1876-1879',\n", " '1885-1895', '1852-1855', '1884-1909', '1873-1887', '1979',\n", " '1852-1941', '1951', '1862-1871', '1871-1873', '1885-1886',\n", " '1886-1893', '1919', '1920', '1946', '1888-1889', '1898-1901',\n", " '1928', '1897-1901', '1872-1878', '1851-1871', '1870-1895',\n", " '1867-1904', '1888-1890', '1884-', '1882-1890', '1955',\n", " '1898-1912', '1892-1901', '1835-1836', '1869-1872', '1885-1900',\n", " '1860-1863', '1931', '1933', '1953', '1952', '1929', '1943',\n", " '1954', '1935', '1945', '1934', '1930', '1944', '1942', '1947',\n", " '1950'], dtype=object)" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Date of publication'].unique()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice the varying ways in which the date of publication is recorded. Mostly, the value comprises just a number, but sometimes it indicates a data range, such as '1884-1909'. In some cases, the record lacks a start or end year (e.g. '1884-')\n", "\n", "The messiness of these data is fairly typical of heritage collections. The data are often entered manually and the conventions may not always be obvious. Even though the data are structured, they still require some processing to be useable.\n", "\n", "`dtype=object` (at the end of the output returned by `.unique()` indicates that the values are neither numbers nor dates. Selecting rows with the masking technique we introduced earlier, won't work in this case. For example, using the greater than (`>`) operator to obtain all books published after 1850 will produce a TypeError, telling us that numbers and strings are not comparable in this situation." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'>' not supported between instances of 'str' and 'int'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/2_/fcdvqwzs6j75cfr97nggzfn499sjqf/T/ipykernel_39483/2626304343.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Date of publication'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1850\u001b[0m \u001b[0;31m# this raises an error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/ops/common.py\u001b[0m in \u001b[0;36mnew_method\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0mother\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mitem_from_zerodim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 69\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 70\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mnew_method\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/arraylike.py\u001b[0m in \u001b[0;36m__gt__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 46\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0munpack_zerodim_and_defer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"__gt__\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 47\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__gt__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 48\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmp_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moperator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 49\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0munpack_zerodim_and_defer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"__ge__\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/series.py\u001b[0m in \u001b[0;36m_cmp_method\u001b[0;34m(self, other, op)\u001b[0m\n\u001b[1;32m 5499\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5500\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merrstate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"ignore\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 5501\u001b[0;31m \u001b[0mres_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mops\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcomparison_op\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5502\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5503\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_construct_result\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres_values\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mres_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/ops/array_ops.py\u001b[0m in \u001b[0;36mcomparison_op\u001b[0;34m(left, right, op)\u001b[0m\n\u001b[1;32m 282\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 283\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mis_object_dtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlvalues\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 284\u001b[0;31m \u001b[0mres_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcomp_method_OBJECT_ARRAY\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 285\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 286\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/core/ops/array_ops.py\u001b[0m in \u001b[0;36mcomp_method_OBJECT_ARRAY\u001b[0;34m(op, x, y)\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlibops\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvec_compare\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mravel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mravel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 72\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 73\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlibops\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscalar_compare\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mravel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 74\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 75\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.7/site-packages/pandas/_libs/ops.pyx\u001b[0m in \u001b[0;36mpandas._libs.ops.scalar_compare\u001b[0;34m()\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: '>' not supported between instances of 'str' and 'int'" ] } ], "source": [ "df['Date of publication'] > 1850 # this raises an error" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So let's convert the date of publication to integers. First we discard all rows with missing information. When applied to a column the `.isnull()` method returns `True` for all rows with NaN value (for the selected column)." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BL record ID\n", "14602826 False\n", "14602830 False\n", "14602831 False\n", "14602832 False\n", "14602833 False\n", " ... \n", "16289058 True\n", "16289059 True\n", "16289060 False\n", "16289061 False\n", "16289062 False\n", "Name: Date of publication, Length: 52695, dtype: bool" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Date of publication'].isnull()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But we want the opposite, i.e. `True` for the rows where we **have** date information. For this we can use the tilde (`~`) or negation symbol." ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BL record ID\n", "14602826 True\n", "14602830 True\n", "14602831 True\n", "14602832 True\n", "14602833 True\n", " ... \n", "16289058 False\n", "16289059 False\n", "16289060 True\n", "16289061 True\n", "16289062 True\n", "Name: Date of publication, Length: 52695, dtype: bool" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "~df['Date of publication'].isnull()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can save the result of this operation as a new mask..." ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "has_date_mask = ~df['Date of publication'].isnull()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "... and use the mask variable to select all rows with date information. We save the resulting data frame in a new variable called `df_s`. To keep track of the information we are throwing away, we print the `.shape` attribute of the original data frame `df` and `df_s`. As you'll notice, we are not discarding many rows: we only have around 175 missing values in \"Date of publication\"." ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(52695, 23) (52517, 23)\n" ] } ], "source": [ "df_s = df[has_date_mask]\n", "print(df.shape,df_s.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we create a new function that converts a string to an integer. We use the typecasting function `int()` to convert the string. " ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2016 \n" ] } ], "source": [ "year_as_int = int('2016')\n", "print(year_as_int,type(year_as_int))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is one more step left: handling the date ranges marked with a hyphen between two years. To simplify matters we only keep the first year mentioned in the date range. We obtain this number by splitting a string on the hyphen (`.split()`).\n", "\n", "Please remember that `split()` always returns a list. We use the index notation to retrieve the first element of the list `[0]` (in Python we count from zero!).\n", "\n", "Run the cells below to understand how this works." ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['2005']" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'2005'.split('-')" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2005'" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'2005'.split('-')[0]" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['2000', '2019']" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'2000-2019'.split('-')" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2000'" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'2000-2019'.split('-')[0]" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2000'" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'2000-2019'.split('-')[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Combining these steps with `int()` will convert a date range to a number." ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2000" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "int('2000-2019'.split('-')[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can package all these steps in one function. The function takes a string as input (`date_string`), splits it, and returns the element before the hyphen." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "def get_first_year(date_string):\n", " return int(date_string.lstrip('-').split('-')[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function produces the same output as the lines of code above." ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2005" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "get_first_year('2005')" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2000" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "get_first_year('2000-2019')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To retrieve the first year of publication we have to apply `get_first_year()` to each value in the 'Date of publication' column. Luckily, this is very easy to do in Pandas with the `.apply()` method. `.apply()` takes a function as an argument—in this case, `get_first_year`—and will apply it (ha, what's in a name) to each value in the selected column. \n", "\n", "Basically, it returns a new column that contains a transformation from another column.\n", "\n", "For example, the code below returns a new column that contains the first year mentioned in the 'Date of publication' column. \n", "\n", "`df_s.loc[:,'Date of publication']` selects all rows: `:` means all values from the beginning till the end, for the 'Date of publication' column. The `,` in `.loc` separates the dimension (i.e. rows `,` columns)." ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BL record ID\n", "14602826 1786\n", "14602830 1679\n", "14602831 1816\n", "14602832 1868\n", "14602833 1888\n", " ... \n", "16289056 1936\n", "16289057 1922\n", "16289060 1913\n", "16289061 1924\n", "16289062 1919\n", "Name: Date of publication, Length: 52517, dtype: int64" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_s.loc[:,'Date of publication'].apply(get_first_year)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The transformation also changed the the data type. Notice the `dtype: int64` at the end of the above output.\n", "\n", "We're almost there. As the last step, we want to attach the new column produced by `.apply()` to our data frame `df_s`. Again, the syntax here is very convenient as is shown in the example below." ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.7/site-packages/pandas/core/indexing.py:1667: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " self.obj[key] = value\n" ] } ], "source": [ "df_s.loc[:,'First year of pulication'] = df_s.loc[:,'Date of publication'].apply(get_first_year)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inspect the original data frame with `.head()` At the right-hand side of the table you should observe a new column with the first year of publication now correctly formatted" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Type of resourceNameDates associated with nameType of nameRoleAll namesTitleVariant titlesSeries titleNumber within series...EditionPhysical descriptionDewey classificationBL shelfmarkTopicsGenreLanguagesNotesBL record ID for physical resourceFirst year of pulication
BL record ID
14602826MonographYearsley, Ann1753-1806personNaNMore, Hannah, 1745-1833 [person] ; Yearsley, A...Poems on several occasions [With a prefatory l...NaNNaNNaN...Fourth edition MANUSCRIPT noteNaNNaNDigital Store 11644.d.32NaNNaNEnglishNaN39966031786
14602830MonographA, T.NaNpersonNaNOldham, John, 1653-1683 [person] ; A, T. [person]A Satyr against Vertue. (A poem: supposed to b...NaNNaNNaN...NaN15 pages (4°)NaNDigital Store 11602.ee.10. (2.)NaNNaNEnglishNaN11431679
14602831MonographNaNNaNNaNNaNNaNThe Aeronaut, a poem; founded almost entirely,...NaNNaNNaN...NaN17 pages (8°)NaNDigital Store 992.i.12. (3.)Dublin (Ireland)NaNEnglishNaN227821816
14602832MonographAlbert, Prince Consort, consort of Victoria, Q...1819-1861personNaNPlimsoll, Joseph [person] ; Albert, Prince Con...The Prince Albert, a poem [By Joseph Plimsoll.]AppendixNaNNaN...NaN16 pages (8°)NaNDigital Store 11602.ee.17. (1.)NaNNaNEnglishNaN397751868
14602833MonographAnslow, RobertNaNpersonNaNAnslow, Robert [person]The Defeat of the Spanish Armada, A.D. 1588. A...NaNNaNNaN...NaN40 pages (8°)NaNDigital Store 11602.ee.17. (7.)NaNNaNEnglishNaN926661888
\n", "

5 rows × 24 columns

\n", "
" ], "text/plain": [ " Type of resource \\\n", "BL record ID \n", "14602826 Monograph \n", "14602830 Monograph \n", "14602831 Monograph \n", "14602832 Monograph \n", "14602833 Monograph \n", "\n", " Name \\\n", "BL record ID \n", "14602826 Yearsley, Ann \n", "14602830 A, T. \n", "14602831 NaN \n", "14602832 Albert, Prince Consort, consort of Victoria, Q... \n", "14602833 Anslow, Robert \n", "\n", " Dates associated with name Type of name Role \\\n", "BL record ID \n", "14602826 1753-1806 person NaN \n", "14602830 NaN person NaN \n", "14602831 NaN NaN NaN \n", "14602832 1819-1861 person NaN \n", "14602833 NaN person NaN \n", "\n", " All names \\\n", "BL record ID \n", "14602826 More, Hannah, 1745-1833 [person] ; Yearsley, A... \n", "14602830 Oldham, John, 1653-1683 [person] ; A, T. [person] \n", "14602831 NaN \n", "14602832 Plimsoll, Joseph [person] ; Albert, Prince Con... \n", "14602833 Anslow, Robert [person] \n", "\n", " Title \\\n", "BL record ID \n", "14602826 Poems on several occasions [With a prefatory l... \n", "14602830 A Satyr against Vertue. (A poem: supposed to b... \n", "14602831 The Aeronaut, a poem; founded almost entirely,... \n", "14602832 The Prince Albert, a poem [By Joseph Plimsoll.] \n", "14602833 The Defeat of the Spanish Armada, A.D. 1588. A... \n", "\n", " Variant titles Series title Number within series ... \\\n", "BL record ID ... \n", "14602826 NaN NaN NaN ... \n", "14602830 NaN NaN NaN ... \n", "14602831 NaN NaN NaN ... \n", "14602832 Appendix NaN NaN ... \n", "14602833 NaN NaN NaN ... \n", "\n", " Edition Physical description \\\n", "BL record ID \n", "14602826 Fourth edition MANUSCRIPT note NaN \n", "14602830 NaN 15 pages (4°) \n", "14602831 NaN 17 pages (8°) \n", "14602832 NaN 16 pages (8°) \n", "14602833 NaN 40 pages (8°) \n", "\n", " Dewey classification BL shelfmark \\\n", "BL record ID \n", "14602826 NaN Digital Store 11644.d.32 \n", "14602830 NaN Digital Store 11602.ee.10. (2.) \n", "14602831 NaN Digital Store 992.i.12. (3.) \n", "14602832 NaN Digital Store 11602.ee.17. (1.) \n", "14602833 NaN Digital Store 11602.ee.17. (7.) \n", "\n", " Topics Genre Languages Notes \\\n", "BL record ID \n", "14602826 NaN NaN English NaN \n", "14602830 NaN NaN English NaN \n", "14602831 Dublin (Ireland) NaN English NaN \n", "14602832 NaN NaN English NaN \n", "14602833 NaN NaN English NaN \n", "\n", " BL record ID for physical resource First year of pulication \n", "BL record ID \n", "14602826 3996603 1786 \n", "14602830 1143 1679 \n", "14602831 22782 1816 \n", "14602832 39775 1868 \n", "14602833 92666 1888 \n", "\n", "[5 rows x 24 columns]" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_s.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Converting the recorded date of publication to an integer makes other operations, such as sorting and plotting the data, much easier. It requires the following step:\n", "\n", "- Apply the `value_counts()` method to ' First year of publication' to count how often each year appears in the BLB metadata." ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1897 1480\n", "1896 1415\n", "1895 1277\n", "1893 1207\n", "1890 1185\n", " ... \n", "1602 1\n", "1608 1\n", "1613 1\n", "1628 1\n", "1950 1\n", "Name: First year of pulication, Length: 354, dtype: int64" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_s['First year of pulication'].value_counts()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- For each year, we see the corresponding number of books. We can order these counts chronologically, sorting the values (counts) by their index (year). `sort_index()` does exactly this." ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1510 1\n", "1528 1\n", "1540 1\n", "1556 1\n", "1584 1\n", " ..\n", "1954 2\n", "1955 2\n", "1957 1\n", "1974 1\n", "1979 1\n", "Name: First year of pulication, Length: 354, dtype: int64" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_s['First year of pulication'].value_counts().sort_index()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- The focus of the BLB corpus is largely on the 19th century. However, our dataset does contain some earlier and later works: the oldest book dates from 1510 and the most recent one from 1979. Let's focus on books published between 1800 and 1900. We can use `.loc[]` in combination with a slicing operation (from 1800 to 1900)." ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1800 120\n", "1801 90\n", "1802 108\n", "1803 100\n", "1804 117\n", " ... \n", "1896 1415\n", "1897 1480\n", "1898 1119\n", "1899 876\n", "1900 123\n", "Name: First year of pulication, Length: 101, dtype: int64" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_s['First year of pulication'].value_counts().sort_index().loc[1800:1900]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- These three steps count the number of books published each year and sort them in chronological order. After slicing, we can plot the number of books by year by appending the `.plot(figsize=(20,5))` method to this sequence of operations (`figsize=(20,5)` regulates the size of the figure)." ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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ZlpSNCPjQ0+6RlBGfgXLduUBcNFpvZqVbPqhvfkVPPRBCqv2FJAUG8wfLx5Gcv8IcktrWLQ1i/c3Z5J2uAIfTw/OGRrNZWPimTIoCm9PjSASEREREREROR4lijqRlOxS/rp0N1/tzic62Jd7zk7kynG9jztFqqbewZq9BSzdcZgvUg9TWPnjoW6BPp70iQikb2RA42NE42NUsC+b9hfz5a7DrNpTQFWdAz9vDyYPjGR6UgzTk6KJDWl5IqcjWGtZmnKYRz7aSVZJNUN79iA1twxrYWyfMOaMiePCEb0ICXDv6CwRERERERGRU4kSRZ3Qhv1F/OXT3azfX0RCeAA/PzeRi0+LOzKap6ymnq925fFZymGW786jss5BkK8X05KimTEshskDIymuqmd/YSUHCirZX1jFgcJKDhRWcai4inrH9/9ee4b4MT0pmrOHRHP6gEj8vFs2ksmdquscPLM8neVp+Zw1KIpLx8RrxTARERERERGRVlKiqJOy1rI8LZ+/fLqbnTllDI4J5pLRcazNKGTN3gLqHZbIIF/OHRrDjGExTBoQga/XiRM8DQ4nOaU1HCisIru0muG9QhjSM/iEU9NEREREREREpOtToqiTczotS3bk8NhnaWQUVNInIoAZw2KZMSyG0b3Dvrc6mIiIiIiIiIjIyTheosiro4ORH/PwMFw4shczh8VyuLyWXiF+Gv0jIiIiIiIiIh1OiaJOxMvTg7hQf3eHISIiIiIiIiLdlNYSFxERERERERERQIkiERERERERERFxUaJIREREREREREQAJYpERERERERERMRFiSIREREREREREQGUKBIRERERERERERclikREREREREREBFCiSEREREREREREXJQoEhERERERERERQIkiERERERERERFxMdZad8fQJGNMPnDA3XG0kUigwN1BiJwC1FZEmkdtRaR51FZEmkdtRaR5ukpb6WOtjTrWE506UdSVGGM2WmvHuTsOkc5ObUWkedRWRJpHbUWkedRWRJqnO7QVTT0TERERERERERFAiSIREREREREREXFRoqjjzHd3ACKnCLUVkeZRWxFpHrUVkeZRWxFpni7fVlSjSEREREREREREAI0oEhERERERERERFyWKToIx5kVjTJ4xZsdRx0YZY9YaY7YaYzYaYya4jhtjzJPGmHRjzLfGmDFHXTPPGLPHtc1zx3sRaU8tbCvXuNrIdmPMGmPMaUddM9MYs9vVjh5wx3sRaU8taStHPT/eGNNgjLn8qGPqV6TLamk7Mcac5TqeYoxZcdRx9SnSpbXw81eIMeZDY8w2V1u58ahr1KdIl9ZEWznNGPON6zvJh8aYHkc996Cr79htjJlx1PGu069Ya7W1cgOmAGOAHUcd+wyY5do/H1h+1P4ngAEmAutcx8OBDNdjmGs/zN3vTZu2ttxa2FZO/64NALOOaiuewF6gP+ADbAOGuvu9adPWlltL2orrZ09gGbAEuNx1TP2Kti69tbBPCQV2Agmun6Ndj+pTtHX5rYVt5dfAn137UUCRq22oT9HW5bcm2soGYKpr/ybgEdf+UFef4Qv0c/Ulnl2tX9GIopNgrV1J43+i3zsMfJdtDAGyXfuzgVdto7VAqDGmJzAD+NxaW2StLQY+B2a2f/QiHaclbcVau8bVFgDWAvGu/QlAurU2w1pbByyksV2JdBkt7FcA7gHeA/KOOqZ+Rbq0FraTq4H3rbUHXdd+11bUp0iX18K2YoFgY4wBglzXNaA+RbqBJtrKIGCla/9z4DLX/mxgobW21lq7D0insU8NicjSAAADQklEQVTpUv2Kl7sD6IJ+Biw1xvyVxql9p7uOxwGHjjov03WsqeMiXV1TbeVoN9M4Eg+O3VaS2zVCkc7hmG3FGBMHXApMA8Yfdb76FemOmupTBgHexpjlQDDwhLX2VdSnSPfVVFt5CviAxsRRMHCltdbp6mvUp0h3lEJjomcR8BOgt+t4HI2/zP7O0W2iy/QrGlHU9u4Afm6t7Q38HHjBzfGIdFbHbSvGmGk0Jorud0NsIp1JU23lceB+a63TbZGJdB5NtRMvYCxwAY0jI35njBnknhBFOoWm2soMYCvQCxgFPHV0TRaRbugm4E5jzCYak6d1bo6nQylR1PbmAe+79t+lcQgaQBb/yUJC43SarOMcF+nqmmorGGNGAs8Ds621ha7DaivSXTXVVsYBC40x+4HLgaeNMZegtiLdU1PtJBNYaq2ttNYW0DiN4DTUTqT7aqqt3EjjNE1rrU0H9gFJqK1IN2Wt3WWtPc9aOxZ4i8b6Q9BNvtcrUdT2soGprv3pwB7X/gfA9a7VzyYCpdbaHGApcJ4xJswYEwac5zom0tUds60YYxJo/ABznbU27ajzNwCJxph+xhgf4Coa25VIV3fMtmKt7Wet7Wut7Qv8C7jTWrsI9SvSPTX1+WsxMNkY42WMCaBxGkAq6lOk+2qqrRwEzgYwxsQAg2ksXK0+RbolY0y069ED+C3wrOupD4CrjDG+xph+QCKwni7Wr6hG0UkwxrwFnAVEGmMygT8AtwJPGGO8gBrgNtfpS2hcWSAdqKIxa4+1tsgY8wiN/7AAHrbW/rCQlsgprYVt5fdABI2jIwAarLXjrLUNxpi7afxw4gm8aK1N6dh3ItK+WthWjkn9inR1LWkn1tpUY8ynwLeAE3jeWrvD9TrqU6RLa2Gf8gjwsjFmO42rNN/vGoWH+hTp6ppoK0HGmLtcp7wPvARgrU0xxrxD44qaDcBd1lqH63W6TL9iXEu8iYiIiIiIiIhIN6epZyIiIiIiIiIiAihRJCIiIiIiIiIiLkoUiYiIiIiIiIgIoESRiIiIiIiIiIi4KFEkIiIiIiIiIiKAEkUiIiIiIiIiIuKiRJGIiIiIiIiIiABKFImIiIiIiIiIiMv/B6w2PSmpgsJ9AAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df_s['First year of pulication'].value_counts().sort_index().loc[1800:1900].plot(figsize=(20,5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.4 Additional Examples\n", "\n", "An excellent and more complete introduction to Pandas is available online: [Python Data Science Handbook](\n", "https://jakevdp.github.io/PythonDataScienceHandbook/) by Jake VanderPlas.\n", "\n", "We provide a few more examples of useful code for interrogating Pandas DataFrame. Please consult the book for more information." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Select rows based on two or more conditions." ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Type of resourceNameDates associated with nameType of nameRoleAll namesTitleVariant titlesSeries titleNumber within series...EditionPhysical descriptionDewey classificationBL shelfmarkTopicsGenreLanguagesNotesBL record ID for physical resourceFirst year of pulication
BL record ID
14804303MonographAubert De La Faige, Geneste ÉmileNaNpersonNaNLa Boutresse, Roger de [person] ; Tiersonnier,...Les Fiefs du Bourbonnais. La Palisse, etc. (Mo...NaNNaNNaN...NaN2 tomes (folio)NaNDigital Store 10172.i.19NaNNaNFrenchNaN1381051936
14804601MonographBarcelona, Concell de CentNaNorganisationNaNBarcelona, Concell de Cent [organisation]Manual de novells ardits vulgarment apellat Di...NaNColecció de documents histórichs inedits de Ar...NaN...NaN17 volumes (8°)NaNDigital Store 10161.eee.6NaNNaNSpanishNaN1968001922
14804602MonographArxiu Municipal Históric (Barcelona)NaNorganisationNaNArxiu Municipal Históric (Barcelona) [organisa...Colecció de documents histórichs inédits del A...NaNNaNNaN...NaNNaNNaNDigital Store 10161.eee.6NaNNaNSpanishOther volume are entered under the authers names1968391922
14809508MonographDubois, Marcel, Maître à l'Ecole normale supér...NaNpersonNaNGuy, Camille [person] ; Dubois, Marcel, Maître...Album géographique [With illustrations.]NaNNaNNaN...NaN5 volumes (4°)NaNDigital Store 10002.i.5NaNNaNFrenchNaN9912431906
14815227MonographKirchhoff, AlfredNaNpersonNaNKirchhoff, Alfred [person]Unser Wissen von der Erde. Allgemeine Erdkunde...NaNNaNNaN...NaN4 Band (8°)NaNDigital Store 10001.g.6NaNNaNGermanNaN19744311907
..................................................................
15742966MonographMilyukov, Pavel NikolaevichNaNpersonNaNMilyukov, Pavel Nikolaevich [person]Очерки по исторіи Русской Культуры ... 3-е изд...NaNNaNNaN...NaN3 част (8°)NaNDigital Store 9454.g.37NaNNaNRussianЧаст. 2 is of the 2nd edition and част. 3 is i...25031231903
15742968MonographMorselli, EnricoNaNpersonNaNVigo, G. B. [person] ; Raverdino, G. [person] ...Antropologia generale. Lezioni su l'uomo secon...NaNNaNNaN...NaNxxxi, 1395 pages (8°)NaNDigital Store 10007.v.5NaNNaNItalianNaN25581771911
16285845MonographRae, Milne, Mrs1844-1933personNaNRae, Milne, Mrs, 1844-1933 [person]Bride LorraineNaNNaNNaN...NaN192 pagesNaNNaNNaNNaNNaNNaN30283141912
16287370MonographLima, Archer deNaNpersonNaNLima, Archer de [person] ; Teisser, P. Carducc...Due Vite. Poema doloroso. (Traduzione di P. Ca...NaNNaNNaN...NaN48 pages (8°)NaNDigital Store 011650.i.6. (2.)NaNNaNItalianNaN21702661909
16288441MonographSmith, D.NaNpersonwriterSmith, D., writer [person]SongsNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaN34146941909
\n", "

108 rows × 24 columns

\n", "
" ], "text/plain": [ " Type of resource \\\n", "BL record ID \n", "14804303 Monograph \n", "14804601 Monograph \n", "14804602 Monograph \n", "14809508 Monograph \n", "14815227 Monograph \n", "... ... \n", "15742966 Monograph \n", "15742968 Monograph \n", "16285845 Monograph \n", "16287370 Monograph \n", "16288441 Monograph \n", "\n", " Name \\\n", "BL record ID \n", "14804303 Aubert De La Faige, Geneste Émile \n", "14804601 Barcelona, Concell de Cent \n", "14804602 Arxiu Municipal Históric (Barcelona) \n", "14809508 Dubois, Marcel, Maître à l'Ecole normale supér... \n", "14815227 Kirchhoff, Alfred \n", "... ... \n", "15742966 Milyukov, Pavel Nikolaevich \n", "15742968 Morselli, Enrico \n", "16285845 Rae, Milne, Mrs \n", "16287370 Lima, Archer de \n", "16288441 Smith, D. \n", "\n", " Dates associated with name Type of name Role \\\n", "BL record ID \n", "14804303 NaN person NaN \n", "14804601 NaN organisation NaN \n", "14804602 NaN organisation NaN \n", "14809508 NaN person NaN \n", "14815227 NaN person NaN \n", "... ... ... ... \n", "15742966 NaN person NaN \n", "15742968 NaN person NaN \n", "16285845 1844-1933 person NaN \n", "16287370 NaN person NaN \n", "16288441 NaN person writer \n", "\n", " All names \\\n", "BL record ID \n", "14804303 La Boutresse, Roger de [person] ; Tiersonnier,... \n", "14804601 Barcelona, Concell de Cent [organisation] \n", "14804602 Arxiu Municipal Históric (Barcelona) [organisa... \n", "14809508 Guy, Camille [person] ; Dubois, Marcel, Maître... \n", "14815227 Kirchhoff, Alfred [person] \n", "... ... \n", "15742966 Milyukov, Pavel Nikolaevich [person] \n", "15742968 Vigo, G. B. [person] ; Raverdino, G. [person] ... \n", "16285845 Rae, Milne, Mrs, 1844-1933 [person] \n", "16287370 Lima, Archer de [person] ; Teisser, P. Carducc... \n", "16288441 Smith, D., writer [person] \n", "\n", " Title \\\n", "BL record ID \n", "14804303 Les Fiefs du Bourbonnais. La Palisse, etc. (Mo... \n", "14804601 Manual de novells ardits vulgarment apellat Di... \n", "14804602 Colecció de documents histórichs inédits del A... \n", "14809508 Album géographique [With illustrations.] \n", "14815227 Unser Wissen von der Erde. Allgemeine Erdkunde... \n", "... ... \n", "15742966 Очерки по исторіи Русской Культуры ... 3-е изд... \n", "15742968 Antropologia generale. Lezioni su l'uomo secon... \n", "16285845 Bride Lorraine \n", "16287370 Due Vite. Poema doloroso. (Traduzione di P. Ca... \n", "16288441 Songs \n", "\n", " Variant titles \\\n", "BL record ID \n", "14804303 NaN \n", "14804601 NaN \n", "14804602 NaN \n", "14809508 NaN \n", "14815227 NaN \n", "... ... \n", "15742966 NaN \n", "15742968 NaN \n", "16285845 NaN \n", "16287370 NaN \n", "16288441 NaN \n", "\n", " Series title \\\n", "BL record ID \n", "14804303 NaN \n", "14804601 Colecció de documents histórichs inedits de Ar... \n", "14804602 NaN \n", "14809508 NaN \n", "14815227 NaN \n", "... ... \n", "15742966 NaN \n", "15742968 NaN \n", "16285845 NaN \n", "16287370 NaN \n", "16288441 NaN \n", "\n", " Number within series ... Edition Physical description \\\n", "BL record ID ... \n", "14804303 NaN ... NaN 2 tomes (folio) \n", "14804601 NaN ... NaN 17 volumes (8°) \n", "14804602 NaN ... NaN NaN \n", "14809508 NaN ... NaN 5 volumes (4°) \n", "14815227 NaN ... NaN 4 Band (8°) \n", "... ... ... ... ... \n", "15742966 NaN ... NaN 3 част (8°) \n", "15742968 NaN ... NaN xxxi, 1395 pages (8°) \n", "16285845 NaN ... NaN 192 pages \n", "16287370 NaN ... NaN 48 pages (8°) \n", "16288441 NaN ... NaN NaN \n", "\n", " Dewey classification BL shelfmark Topics \\\n", "BL record ID \n", "14804303 NaN Digital Store 10172.i.19 NaN \n", "14804601 NaN Digital Store 10161.eee.6 NaN \n", "14804602 NaN Digital Store 10161.eee.6 NaN \n", "14809508 NaN Digital Store 10002.i.5 NaN \n", "14815227 NaN Digital Store 10001.g.6 NaN \n", "... ... ... ... \n", "15742966 NaN Digital Store 9454.g.37 NaN \n", "15742968 NaN Digital Store 10007.v.5 NaN \n", "16285845 NaN NaN NaN \n", "16287370 NaN Digital Store 011650.i.6. (2.) NaN \n", "16288441 NaN NaN NaN \n", "\n", " Genre Languages \\\n", "BL record ID \n", "14804303 NaN French \n", "14804601 NaN Spanish \n", "14804602 NaN Spanish \n", "14809508 NaN French \n", "14815227 NaN German \n", "... ... ... \n", "15742966 NaN Russian \n", "15742968 NaN Italian \n", "16285845 NaN NaN \n", "16287370 NaN Italian \n", "16288441 NaN NaN \n", "\n", " Notes \\\n", "BL record ID \n", "14804303 NaN \n", "14804601 NaN \n", "14804602 Other volume are entered under the authers names \n", "14809508 NaN \n", "14815227 NaN \n", "... ... \n", "15742966 Част. 2 is of the 2nd edition and част. 3 is i... \n", "15742968 NaN \n", "16285845 NaN \n", "16287370 NaN \n", "16288441 NaN \n", "\n", " BL record ID for physical resource First year of pulication \n", "BL record ID \n", "14804303 138105 1936 \n", "14804601 196800 1922 \n", "14804602 196839 1922 \n", "14809508 991243 1906 \n", "14815227 1974431 1907 \n", "... ... ... \n", "15742966 2503123 1903 \n", "15742968 2558177 1911 \n", "16285845 3028314 1912 \n", "16287370 2170266 1909 \n", "16288441 3414694 1909 \n", "\n", "[108 rows x 24 columns]" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_s[(df_s['First year of pulication'] > 1900) & (df_s['Languages'] != 'English')]" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BL record ID\n", "14815227 Unser Wissen von der Erde. Allgemeine Erdkunde...\n", "14823900 Russland in Asien. Bd. 1-11\n", "14847330 Versuch über die Ungleichheit der Menschenrace...\n", "14861142 Weltgeschichte ... Dritte verbesserte Auflage....\n", "14867365 Geschichte der Stadt Pressburg ... Herausgegeb...\n", "14867456 Die Geschichte Husums im Rahmen der Geschichte...\n", "14867692 Das Bisthum Augsburg, historisch und statistis...\n", "14867824 Die Gemeinde-Verwaltung der Reichshaupt und Re...\n", "14867867 Kulmbach und die Plassenburg in alter und neue...\n", "14871193 Nordische Fahrten. Skizzen und Studien\n", "14891317 Geschichte des Königreichs Hannover, etc. 2 Tl...\n", "14891669 Die Berner Chronik des Diebold Schilling, 1468...\n", "14896011 Oesterreichischer Erbfolge-Krieg 1740-1748. Na...\n", "14896217 Die Könige der Germanen. Das Wesen des älteste...\n", "14896882 Fürst Bismarck und der Bundesrat\n", "14897057 Monographien zur deutschen Kulturgeschichte, h...\n", "14897106 Geschichte der Siebenbürger Sachsen für das sä...\n", "14905437 Das Herzogtum Schleswig in seiner ethnographis...\n", "14905541 Geschichte der k. und k. Wehrmacht, etc\n", "14912765 Bibliothek deutscher Geschichte ... Herausgege...\n", "14939924 Bibliothek livländischer Geschichte herausgege...\n", "15105866 Acta Publica. Verhandlungen und Correspondenze...\n", "15115747 Englische Geschichte im achtzehnten Jahrhundert\n", "Name: Title, dtype: object" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_s[(df_s['First year of pulication'] > 1900) & (df_s['Languages'] == 'German')]['Title']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Compare subsections of the corpus and plot a timeline." ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [], "source": [ "df_en = df_s[df_s.Languages=='English']\n", "df_de = df_s[df_s.Languages=='German']" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df_en['First year of pulication'].value_counts().sort_index().loc[1800:1900].plot()\n", "df_de['First year of pulication'].value_counts().sort_index().loc[1800:1900].plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Plot the prevalence of words over time." ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [], "source": [ "import re\n", "pattern = re.compile(r'\\bwoman\\b|\\bwomen\\b',flags= re.I)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Women', 'woman']" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pattern.findall('Women woman bwomena')" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [], "source": [ "def in_title(title,pattern):\n", " return bool(pattern.findall(str(title)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Use `.apply()` with an additional keyword argument." ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " \"\"\"Entry point for launching an IPython kernel.\n" ] } ], "source": [ "df_s['travel'] = df_s.Title.apply(in_title,pattern=pattern)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df_s[df_s['travel'] == True]['First year of pulication'].value_counts().sort_index().plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Fin." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 2 }