- •Об авторе
- •О научном редакторе
- •От издательства
- •Введение
- •Использование Python для data science
- •Для кого эта книга?
- •О чем эта книга?
- •Глава 1. Базовые знания о данных
- •Категории данных
- •Неструктурированные данные
- •Структурированные данные
- •Слабоструктурированные данные
- •Данные временных рядов
- •Источники данных
- •Веб-страницы
- •Базы данных
- •Файлы
- •Получение
- •Очистка
- •Преобразование
- •Анализ
- •Хранение
- •Питонический стиль
- •Выводы
- •Глава 2. Структуры данных Python
- •Списки
- •Создание списка
- •Использование общих методов списков
- •Использование срезов
- •Использование списка в качестве очереди
- •Использование списка в качестве стека
- •Использование списков и стеков для обработки естественного языка
- •Расширение функциональности с помощью списковых включений
- •Кортежи
- •Список кортежей
- •Неизменяемость
- •Словари
- •Список словарей
- •Добавление элементов в словарь с помощью setdefault()
- •Преобразование JSON в словарь
- •Множества
- •Удаление дубликатов из последовательности
- •Общие операции с множеством
- •Упражнение № 1: продвинутый анализ тегов фотографий
- •Выводы
- •NumPy
- •Установка NumPy
- •Создание массива NumPy
- •Выполнение поэлементных операций
- •Использование статистических функций NumPy
- •Упражнение № 2: использование статистических функций numpy
- •pandas
- •Установка pandas
- •pandas Series
- •Упражнение № 3: объединение трех серий
- •pandas DataFrame
- •Упражнение № 4: использование разных типов join
- •scikit-learn
- •Установка scikit-learn
- •Получение набора образцов
- •Преобразование загруженного датасета в pandas DataFrame
- •Разделение набора данных на обучающий и тестовый
- •Преобразование текста в числовые векторы признаков
- •Обучение и оценка модели
- •Создание прогнозов на новых данных
- •Выводы
- •Глава 4. Доступ к данным из файлов и API
- •Импортирование данных с помощью функции open()
- •Текстовые файлы
- •Файлы с табличными данными
- •Упражнение № 5: открытие json-файлов
- •Двоичные файлы
- •Экспортирование данных в файл
- •Доступ к удаленным файлам и API
- •Как работают HTTP-запросы
- •Библиотека urllib3
- •Библиотека Requests
- •Упражнение № 6: доступ к api с помощью requests
- •Перемещение данных в DataFrame и из него
- •Импортирование вложенных структур JSON
- •Конвертирование DataFrame в JSON
- •Выводы
- •Глава 5. Работа с базами данных
- •Реляционные базы данных
- •Понимание инструкций SQL
- •Начало работы с MySQL
- •Определение структуры базы данных
- •Вставка данных в БД
- •Запрос к базе данных
- •Упражнение № 8: объединение «один-ко-многим»
- •Использование инструментов аналитики баз данных
- •Базы данных NoSQL
- •Документоориентированные базы данных
- •Упражнение № 9: вставка и запрос нескольких документов
- •Выводы
- •Глава 6. Агрегирование данных
- •Данные для агрегирования
- •Объединение датафреймов
- •Группировка и агрегирование данных
- •Просмотр конкретных агрегированных показателей по MultiIndex
- •Срез диапазона агрегированных значений
- •Срезы на разных уровнях агрегирования
- •Добавление общего итога
- •Добавление промежуточных итогов
- •Выбор всех строк в группе
- •Выводы
- •Глава 7. Объединение датасетов
- •Объединение встроенных структур данных
- •Объединение списков и кортежей с помощью оператора +
- •Объединение словарей с помощью оператора **
- •Объединение строк из двух структур
- •Реализация join-объединений списков
- •Конкатенация массивов NumPy
- •Объединение структур данных pandas
- •Конкатенация датафреймов
- •Удаление столбцов/строк из датафрейма
- •Join-объединение двух датафреймов
- •Выводы
- •Глава 8. Визуализация
- •Распространенные способы визуализации
- •Линейные диаграммы
- •Столбчатые диаграммы
- •Круговые диаграммы
- •Гистограммы
- •Построение графиков с помощью Matplotlib
- •Установка Matplotlib
- •Использование matplotlib.pyplot
- •Работа с объектами Figure и Axes
- •Создание гистограммы с помощью subplots()
- •Совместимость Matplotlib с другими библиотеками
- •Построение графиков для данных pandas
- •Отображение данных геолокации с помощью Cartopy
- •Выводы
- •Глава 9. Анализ данных о местоположении
- •Получение данных о местоположении
- •Преобразование стандартного вида адреса в геокоординаты
- •Получение геокоординат движущегося объекта
- •Анализ пространственных данных с помощью geopy и Shapely
- •Поиск ближайшего объекта
- •Поиск объектов в определенной области
- •Объединение двух подходов
- •Упражнение № 15: совершенствование алгоритма подбора машины
- •Получение непространственных характеристик
- •Объединение датасетов с пространственными и непространственными данными
- •Выводы
- •Глава 10. Анализ данных временных рядов
- •Регулярные и нерегулярные временные ряды
- •Общие методы анализа временных рядов
- •Вычисление процентных изменений
- •Вычисление скользящего окна
- •Вычисление процентного изменения скользящего среднего
- •Многомерные временные ряды
- •Обработка многомерных временных рядов
- •Анализ зависимости между переменными
- •Выводы
- •Глава 11. Получение инсайтов из данных
- •Ассоциативные правила
- •Поддержка
- •Доверие
- •Лифт
- •Алгоритм Apriori
- •Создание датасета с транзакциями
- •Определение часто встречающихся наборов
- •Генерирование ассоциативных правил
- •Визуализация ассоциативных правил
- •Получение полезных инсайтов из ассоциативных правил
- •Генерирование рекомендаций
- •Планирование скидок на основе ассоциативных правил
- •Выводы
- •Глава 12. Машинное обучение для анализа данных
- •Почему машинное обучение?
- •Типы машинного обучения
- •Обучение с учителем
- •Обучение без учителя
- •Как работает машинное обучение
- •Данные для обучения
- •Статистическая модель
- •Неизвестные данные
- •Пример анализа тональности: классификация отзывов о товарах
- •Получение отзывов о товарах
- •Очистка данных
- •Разделение и преобразование данных
- •Обучение модели
- •Оценка модели
- •Упражнение № 19: расширение набора примеров
- •Прогнозирование тенденций фондового рынка
- •Получение данных
- •Извлечение признаков из непрерывных данных
- •Генерирование выходной переменной
- •Обучение и оценка модели
- •Выводы
114 Глава 5. Работа с базами данных
На этот раз мы добавляем ограничение внешнего ключа внутри команды CREATE TABLE, тем самым определяя внешний ключ сразу после создания таблицы.
Вставка данных в БД
Теперь все готово, чтобы вставлять строки во вновь созданные таблицы. Хотя это можно сделать в командной строке mysql>, данная операция обычно выполняется из приложения. Мы будем взаимодействовать с базой данных из Python-кода через драйвер MySQL Connector/Python. Его можно установить с помощью команды pip, как показано ниже:
$ pip install mysql-connector-python
Запустите следующий скрипт, чтобы заполнить таблицы БД данными:
import mysql.connector
try:
cnx = mysql.connector.connect(user='root', password='your_pswd', host='127.0.0.1', database='sampledb')
cursor = cnx.cursor()
# объявление строк с сотрудниками
emps = [
(9001, "Jeff Russell", "sales"),
(9002, "Jane Boorman", "sales"),
(9003, "Tom Heints", "sales")
]
# объявление запроса
query_add_emp = ("""INSERT INTO emps (empno, empname, job)
VALUES (%s, %s, %s)""")
#вставка строк с сотрудниками
for emp in emps:
cursor.execute(query_add_emp, emp)
#определение и вставка размеров оклада
salary = [
(9001, 3000), (9002, 2800), (9003, 2500)
]
query_add_salary = ("""INSERT INTO salary (empno, salary) VALUES (%s, %s)""")
for sal in salary: cursor.execute(query_add_salary, sal)
# объявление и вставка заказов
Понимание инструкций SQL 115
orders = |
[ |
(2608, |
9001, 35), |
(2617, |
9001, 35), |
(2620, |
9001, 139), |
(2621, |
9002, 95), |
(2626, |
9002, 218) |
]
query_add_order = ("""INSERT INTO orders(pono, empno, total) VALUES (%s, %s, %s)""")
for order in orders: cursor.execute(query_add_order, order)
# делаем вставку в БД постоянной
cnx.commit()
except mysql.connector.Error as err: print("Error-Code:", err.errno) print("Error-Message: {}".format(err.msg))
finally: cursor.close() cnx.close()
В скрипте мы импортируем драйвер MySQL Connector/Python как mysql. connector. Затем открываем блок try/except, который предоставляет шаблон для любых операций, связанных с базой данных, выполняемых в скрипте. Код для операции пишем в блоке try, и если при ее выполнении возникает ошибка, срабатывает переход в блок except.
Прежде всего, в блоке try устанавливаем соединение с базой данных, указывая имя пользователя, пароль, IP-адрес хоста (в данном случае локального хоста) и имя БД . Затем получаем объект cursor, связанный с этим соединением . Объект cursor предоставляет средства для выполнения инструкции, а также интерфейс для получения результатов.
Определяем строки для таблицы emps как список кортежей . Затем объявляем инструкцию SQL для вставки этих строк в таблицу . В инструкции INSERT указываем поля, которые должны быть заполнены данными, а также заполнители %s, которые сопоставляют эти поля с элементами каждого кортежа. Выполняем инструкцию в цикле, вставляя строки по одной с помощью метода cursor.execute() . Аналогичным образом вставляем строки в таблицы salary и orders. В конце блока try делаем все вставки в базу данных с помощью метода commit() .
Если какая-либо операция, связанная с базой данных, завершается сбоем, остальная часть блока try пропускается и выполняется пункт except , выводя код ошибки, сгенерированный сервером MySQL, и соответствующее сообщение об ошибке.
116 Глава 5. Работа с базами данных
Блок finally выполняется в любом случае . В этом блоке мы явно закрываем cursor, а затем и соединение.
Запрос к базе данных
Теперь, когда мы заполнили таблицы информацией, можно запросить эти данные, чтобы дальше использовать их в Python-коде. Допустим, требуется получить все строки из таблицы emps, где значение поля empno больше 9001. Для этого в качестве образца будем использовать скрипт из предыдущего раздела, изменив только блок try следующим образом:
--фрагмент-- try:
cnx = mysql.connector.connect(user='root', password='your_pswd', host='127.0.0.1', database='sampledb')
cursor = cnx.cursor()
query = ("SELECT * FROM emps WHERE empno > %s")
empno = 9001
cursor.execute(query, (empno,))
for (empno, empname, job) in cursor: print("{}, {}, {}".format(
empno, empname, job))
--фрагмент--
Вотличие от операции вставки, для выбора строк не нужно выполнять операцию cursor.execute() в цикле для каждой строки. Вместо этого мы пишем запрос, указывающий критерии для выбора строк, а затем получаем их все разом с помощью одной операции cursor.execute().
Винструкции SELECT, которая формирует наш запрос, мы указываем символ
звездочки (*), это означает, что необходимо отобразить все поля извлеченных строк . В блоке WHEREпрописывается условие, которому должна удовлетворять
выбранная строка. Здесь мы указываем, что у данной строки значение поля empno должно быть больше, чем значение переменной, связанной с заполнителем %s . Во время выполнения переменная empno связана с заполнителем . Когда мы
делаем запрос с помощью cursor.execute(), мы передаем связанную переменную из кортежа в качестве второго параметра . Метод execute() требует, чтобы связанные переменные передавались в кортеже или в словаре, даже если необходима только одна переменная.
Доступ к полученным строкам осуществляется через итерацию по объекту cursor с помощью цикла. Каждая строка хранится в виде кортежа, элементы которого
Понимание инструкций SQL 117
представляют собой значения полей этой строки . Значения полей выводятся строка за строкой:
9002, Jane Boorman, sales 9003, Tom Heints, sales
Можно написать инструкции SELECT, которые объединяют строки из разных таблиц. Объединение таблиц реляционной базы данных повторяет процесс объединения датафреймов pandas, который был описан в главе 3. Обычно таблицы объединяются с помощью отношений внешнего ключа, определяемого при настройке базы данных.
Предположим, что необходимо объединить таблицы emps и salary, сохраняя условие о том, что значение empno должно быть больше 9001. Мы делаем это через их общие столбцы (empno), поскольку определили это поле в таблице salary как внешний ключ, ссылающийся на empno в таблице emps. Это соединение можно реализовать с помощью еще одной модификации блока try внутри скрипта:
--фрагмент-- try:
cnx = mysql.connector.connect(user='root', password='your_pswd', host='127.0.0.1', database='sampledb')
cursor = cnx.cursor()
query = ("""SELECT e.empno, e.empname, e.job, s.salary
FROM emps e JOIN salary s ON e.empno = s.empno WHERE e.empno > %s""")
empno = 9001 cursor.execute(query, (empno,))
for (empno, empname, job, salary) in cursor: print("{}, {}, {}, {}".format(
empno, empname, job, salary))
--фрагмент--
На этот раз запрос содержит оператор SELECT, объединяющий таблицы emps и salary. В блоке SELECT перечисляются столбцы из обеих таблиц, которые необходимо включить в объединение . В блоке FROM расположены ключевое слово JOIN и названия таблиц для объединения, вместе с короткими именами e и s, которые необходимы, чтобы различать столбцы с одинаковым именем в обеих таблицах . В блоке ONмы определяем условие объединения, указывая, что значения в столбцах empno обеих таблиц должны совпадать . В блоке WHERE, как и в предыдущем примере, используем заполнитель %s, чтобы установить минимальное значение empno .