Что делать, если вам нужна информация из нескольких разделов статьи

Последние несколько недель я писал о том, как очистить разные вещи со страницы Википедии. Три недели назад я писал о том, как очистить одну таблицу из статьи в Википедии. Две недели назад я писал о том, как использовать один скрипт для очистки данных с нескольких страниц Википедии. Наконец, на прошлой неделе я написал о создании таблицы, в которой для отображения данных используются цвета вместо текста. На этой неделе я собираюсь поговорить о том, как очистить данные из нескольких таблиц.

Как и в течение последних трех недель, мы собираемся работать над статьей о первом сезоне Great British Bake Off. На этой неделе наша цель - получить доступ к информации о том, как пекари решают техническую задачу. Для тех из вас, кто не знаком с форматом шоу: в каждом эпизоде ​​пекари проходят три испытания: подпись, техническое задание и шоу-стоп. Техническая задача состоит в том, что все пекари выпекают одно и то же по рецепту, написанному одним из судей, и эти выпечки оцениваются анонимно и оцениваются от худшего к лучшему. В статье результаты технических испытаний отображаются в таблице, показанной ниже:

Получить информацию из одной диаграммы достаточно просто, и вы можете вернуться к моей первой статье, чтобы освежить в памяти, как это работает. Однако что вы делаете, если хотите получить техническую информацию по всем эпизодам? Об этом будет сказано ниже.

Как и раньше, мы собираемся начать с импорта пакетов и доступа к веб-сайту с помощью BeautifulSoup.

import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
import numpy as np
url='https://en.wikipedia.org/wiki/The_Great_British_Bake_Off_(series_1)'
page = requests.get(url)
soup = BeautifulSoup(page.content)

Кроме того, чтобы получить список пекарей, мы сначала выделим таблицу исключения (ту, с которой мы работали на прошлой неделе).

Затем мы возьмем имена пекарей из этой таблицы, выполнив следующие действия:

Я не буду вдаваться в подробности того, как я получил этот список, поскольку это не является основной темой данной статьи, но, по сути, если элемент в таблице исключения имеет атрибут «выровнять», то текст этого элемента является участником. имя. Также, если «выравнивание» находится в части стиля элемента, текст также является именем участника. Эти имена добавляются в список, и после того, как имена были очищены, все они проходят через .rstrip (), чтобы избавиться от любых символов новой строки. В результате у нас остается список имен участников, который выглядит следующим образом:

['Edd', 'Ruth', 'Miranda', 'Jasminder', 'David', 'Jonathan', 'Annetha', 'Louise', 'Lea', 'Mark']

Теперь все, что нам нужно сделать, это получить все технические результаты запекания. Вот полный код, который мы рассмотрим:

И вот окончательный результат приведенного выше кода:

{1: {'Edd': 0,
  'Ruth': 0,
  'Miranda': 0,
  'Jasminder': 0,
  'David': 0,
  'Jonathan': 0,
  'Annetha': 0,
  'Louise': 0,
  'Lea': 0,
  'Mark': 0},
 2: {'Annetha': 2.0,
  'David': 3.0,
  'Edd': 1.0,
  'Jasminder': 5.5,
  'Jonathan': 9.0,
  'Lea': 10.0,
  'Louise': 5.5,
  'Mark': 5.5,
  'Miranda': 8.0,
  'Ruth': 5.5},
 3: {'Annetha': 7.0,
  'David': 8.0,
  'Edd': 6.0,
  'Jasminder': 2.0,
  'Jonathan': 1.0,
  'Louise': 4.0,
  'Miranda': 3.0,
  'Ruth': 5.0},
 4: {'David': 4.0,
  'Edd': 1.0,
  'Jasminder': 5.0,
  'Jonathan': 6.0,
  'Miranda': 3.0,
  'Ruth': 2.0},
 5: {'David': 5.0, 'Edd': 3.0, 'Jasminder': 2.0, 'Miranda': 1.0, 'Ruth': 4.0},
 6: {'Edd': 2.0, 'Jasminder': 4.0, 'Miranda': 1.0, 'Ruth': 3.0}}

Теперь перейдем к приведенному выше коду. Первые три строки содержат три переменные, «ep_counter», «tech_results_list» и «ep_tech», и представляют собой ноль, пустой список и словарь соответственно. Словарь начинается с ключа, равного 1, а значение - это словарь, где ключи - это имена участников, а все значения равны нулю. Это сделано потому, что если вы используете эти данные для создания модели прогноза, вы хотите получить технический рейтинг из последнего предыдущего эпизода, а не из текущего, который вы анализируете. Очевидно, что в первом эпизоде ​​участники не выполнили технический конкурс и не получили оценок, поэтому им всем были присвоены нули.

Отсюда мы начинаем соскабливать. В первых двух строках (5–6) находятся все заголовки, в которых есть «Эпизод». Затем мы создаем два пустых списка, имена и место. Имена будут иметь имена участников из данного эпизода, а место будет иметь то, как участник попал в технический конкурс в указанном эпизоде. Отсюда мы делаем следующее:

По сути, то, что мы делаем, - это находим эпизоды с техническим запеканием (строка 2 выше), затем берем полную таблицу, называем ее «result_tables» и добавляем ее в счетчик эпизодов. Наконец, мы создаем «ep_list», список номеров, который начинается с двух и заканчивается последним эпизодом (в данном случае 6). Затем погружаемся в таблицу результатов:

Мы начинаем с поиска столбца, который содержит имена участников, что мы делаем, говоря: «Если слово в тексте элемента совпадает с элементом в списке имен участников, добавьте текст этого элемента в список имен». Затем мы проходим две колонки, чтобы понять, как они размещены в своей технической документации. Однако вы, возможно, заметили в статье, что есть одна небольшая проблема:

В первом эпизоде ​​только три верхних и нижних места попали в рейтинг, поэтому мы не знаем, кто занял 4-е, 5-е, 6-е и 7-е места. Поэтому, когда я добавляю текст элемента в список мест, я говорю разделению регулярного выражения либо получить число, которое может состоять из одной или двух цифр (в случае числа десять), либо получить «N / A».

Имея это в виду, как нам справиться с отсутствующими значениями, подобными приведенным выше? Подход, который я выбрал, заключается в том, чтобы взять среднее значение из приведенных выше значений и присвоить это среднее значение отсутствующим значениям, что я сделал, используя приведенный ниже код:

На этом этапе я имел бы дело с полным списком мест размещения, поэтому я начну с того, что если в списке мест есть отметка «Н / Д», выполните следующие действия. Затем я создаю список чисел (num_list), выделяя все числа в этом списке и превращая их в целые числа. Затем я беру среднее значение этого списка (среднее) и заменяю все значения «N / A» в этом списке мест этим средним.

Теперь, когда у нас есть список имен, и все эти имена имеют соответствующие им номера мест размещения, мы можем собрать все это вместе, используя следующее:

place = [float(x) for x in place]
episode_placement = dict(zip(names,place))
tech_results_list.append(episode_placement)

Во-первых, мы делаем все элементы в списке мест плавающими, поскольку раньше они были строками, если только они не были средним значением, которое было заменено на «N / A». Затем мы создаем наш словарь (Episode_placement), где ключи - это имена участников, а значения - это то, как они помещены в технический. Затем мы добавляем этот словарь в список технических результатов, который мы создали в самом начале.

Наконец-то мы можем обновить словарь ep_tech, который мы начали с самого начала. Если вы помните, этот словарь начинался с ключа, равного единице, и значения словаря, содержащего имена всех участников со значениями 0. Теперь, когда у нас есть вся информация для следующих эпизодов, мы можем сделать следующее:

ep_tech.update(dict(zip(ep_list,tech_results_list)))

Таким образом, мы берем этот ep_list, который подсчитывает все эпизоды с техническими проблемами, и делаем элементы в этом списке ключами, а значения - словарями имен и мест размещения в каждом эпизоде. Это приводит нас к выводу, показанному выше:

{1: {'Edd': 0,
  'Ruth': 0,
  'Miranda': 0,
  'Jasminder': 0,
  'David': 0,
  'Jonathan': 0,
  'Annetha': 0,
  'Louise': 0,
  'Lea': 0,
  'Mark': 0},
 2: {'Annetha': 2.0,
  'David': 3.0,
  'Edd': 1.0,
  'Jasminder': 5.5,
  'Jonathan': 9.0,
  'Lea': 10.0,
  'Louise': 5.5,
  'Mark': 5.5,
  'Miranda': 8.0,
  'Ruth': 5.5},
 3: {'Annetha': 7.0,
  'David': 8.0,
  'Edd': 6.0,
  'Jasminder': 2.0,
  'Jonathan': 1.0,
  'Louise': 4.0,
  'Miranda': 3.0,
  'Ruth': 5.0},
 4: {'David': 4.0,
  'Edd': 1.0,
  'Jasminder': 5.0,
  'Jonathan': 6.0,
  'Miranda': 3.0,
  'Ruth': 2.0},
 5: {'David': 5.0, 'Edd': 3.0, 'Jasminder': 2.0, 'Miranda': 1.0, 'Ruth': 4.0},
 6: {'Edd': 2.0, 'Jasminder': 4.0, 'Miranda': 1.0, 'Ruth': 3.0}}

Теперь предположим, что у вас есть уже существующий фрейм данных, в котором есть другие данные об эпизоде, такие как информация о возрасте и родном городе об участниках и о том, как они выступали в предыдущих эпизодах. Я ранее создал этот фрейм данных, и вот снимок того, как он выглядит:

Вот как я использовал этот словарь для создания столбца технического размещения:

Проходя по коду, я начинаю с создания словаря, в котором ключи представляют собой кортежи с именем и эпизодом, а значение - это то, как участник разместил этот эпизод (строки 1–4). Затем я создаю пустой список place_list, который станет технической колонкой. Затем я создаю список кортежей, где каждый кортеж представляет собой имя участника и номер эпизода для каждой строки в кадре данных, показанном выше (строки 6–7). Оттуда я говорю, что для каждого элемента в этом списке кортежей найдите его значение в словаре tech_tuple и добавьте это значение в список размещения. Теперь, когда у меня есть полный список технических мест размещения, я просто создаю новый столбец «технический» и назначаю ему список мест размещения. Так мы получаем следующее:

В этой статье я показал, как рассматривать множество разных областей страницы, а не только одну диаграмму или раздел страницы. Страницы Википедии отформатированы таким образом, что они, как правило, удобны для чтения и просты для пользователя, но это также означает, что данные, которые вы можете искать, должны быть отформатированы и сжаты. Поступая так, вы можете взять эту читаемую информацию и сделать ее пригодной для обработки.