
МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
федеральное государственное автономное образовательное учреждение высшего образования
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»
ИНСТИТУТ НЕПРЕРЫВНОГО И ДИСТАНЦИОННОГО ОБРАЗОВАНИЯ
КАФЕДРА 41 |
ОЦЕНКА
ПРЕПОДАВАТЕЛЬ
кандидат техн. наук |
|
|
|
Е.Л. Турнецкая |
должность, уч. степень, звание |
|
подпись, дата |
|
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №8
|
||||
Визуализация данных из СУБД PostgreSQL в Python |
||||
по курсу: БАЗЫ ДАННЫХ |
РАБОТУ ВЫПОЛНИЛ
СТУДЕНТ ГР. № |
Z9411 |
|
|
|
А.С.Чурилов |
|
номер группы |
|
подпись, дата |
|
инициалы, фамилия |
Студенческий билет № 2019/3684
Санкт-Петербург 2023
Цель работы:
Произвести связь базы данных в PostgreSQL и Python, изучить операции по манипулированию с данными БД, выполнить анализ данных в БД с помощью визуализации в Python.
Ход работы:
Вариант 20 (На оценку 5)
1 По оси х – название отдела, по оси у – количество сотрудников.
2 Найти количество сотрудников, в должности которых фигурирует слово «Manager», найти количество сотрудников, в должности которых фигурирует «Clerk», найти количество сотрудников, в должности которых фигурирует «President», построить гистограмму с 4 столбцами (Manager, Clerk, President, Other), по оси у – средняя зарплата сотрудников по каждой группе
3 Выполнить модификацию первых двух графиков:
3.1 – сделать гистограмму горизонтальной (поменять х и у), изменить цвета,
3.2 - создать процедуру/функцию, которая позволит строить графики для любого числа в условии.
- построить любой график, используя locations
Диаграмма базы данных (Рисунок 1).
Рисунок 1 – Диаграмма базы данных
Листинг 1 – Подключение к БД
if __name__ == '__main__': connection = psycopg2.connect(database="students", user="postgres", password="admin", host="127.0.0.1", port="5432") |
Первый график (Листинг 2, Рисунок 2) – По оси х – название отдела, по оси у – количество сотрудников
Листинг 2 – Код для первого графика, а также его изменение для пунктов 3.1 и 3.2
def employees_number_by_dep(): cursor.execute( """ select department_name, count(e.employee_id) as employees_number from departments d join employees e on e.department_id = d.department_id group by department_name; """ ) return cursor.fetchall()
def plot_deps(min_emp_number, max_emp_number): import matplotlib.pyplot as plt
prop = plt.rcParams['axes.prop_cycle'] plt.figure(figsize=(10, 8)) for v, color in zip(employees_number_by_dep(), prop): dep, number = v if min_emp_number <= number <= max_emp_number: plt.barh(dep, number, color=color['color'])
plt.xlabel('Отделы') plt.ylabel('Количество сотрудников') plt.title(f'Количество сотрудников по отделам\n' f'от {min_emp_number} до {max_emp_number} сотрудников.') plt.show()
plot_deps(3, 10) |
Рисунок 2 – Первый график
Второй график (Листинг 3, Рисунок 3) – Найти количество сотрудников, в должности которых фигурирует слово «Manager», найти количество сотрудников в должности которых фигурирует «Clerk», найти количество сотрудников, в должности которых фигурирует «President», построить гистограмму с 4 столбцами (Manager, Clerk, President, Other), по оси у – средняя зарплата сотрудников по каждой группе.
Листинг 3 – Код для второго графика, а также его изменение для пунктов 3.1 и 3.2
def employees_with_jop_title(job_title=None): if job_title: _job = '%' + job_title + '%' cursor.execute( """ select count(1), avg(salary) as avg_salary from employees e join jobs j on j.job_id = e.job_id where j.job_title ilike (%s); """, (_job,) ) else: cursor.execute( """ select count(1), avg(salary) as avg_salary from employees e join jobs j on j.job_id = e.job_id where j.job_title not ilike '%Clerk%' and j.job_title not ilike '%President%' and j.job_title not ilike '%Manager%'; """ ) _result = cursor.fetchone() return _result[0], float(_result[1])
def jobs(min_avg_salary, max_avg_salary): data = { 'Others': employees_with_jop_title(), 'Managers': employees_with_jop_title('Manager'), 'Presidents': employees_with_jop_title('President'), 'Clerks': employees_with_jop_title('Clerk') } return {v[0]: v[1] for v in data.items() if max_avg_salary >= v[1][1] >= min_avg_salary}
def plot_jobs(min_avg_salary, max_avg_salary): import matplotlib.pyplot as plt
_data = jobs(min_avg_salary, max_avg_salary) prop = plt.rcParams['axes.prop_cycle'] for item, color in zip(_data.items(), prop): plt.barh(item[0], item[1][0], color=color['color'])
plt.xlabel('Должности') plt.ylabel('Количество сотрудников') plt.title(f'Количество сотрудников для должностей\n' f'со средней зарплатой от {min_avg_salary} до {max_avg_salary}.') plt.show()
plot_jobs(5000, 20000) |
Рисунок 3 – Второй график
Третий график (Листинг 4, Рисунок 4) – По оси х – города, по оси у – средняя зп. Запрос с использованием таблицы Locations.
Листинг 4 – Код функции
def plot_locations(): import matplotlib.pyplot as plt cursor.execute(""" with avg_salary as ( select l.city, avg(salary) as salary_average from jobs j join employees e on e.job_id = j.job_id join locations l on l.location_id = e.location_id group by city ) select city, salary_average from avg_salary; """) plt.figure(figsize=(10, 8)) prop = plt.rcParams['axes.prop_cycle'] for v, color in zip(cursor.fetchall(), prop): city, salary_average = v _salary = salary_average _city = city if len(city.split()) == 1 else '\n'.join(city.split()) plt.bar(_city, _salary, color=color['color'])
plt.xlabel('Города') plt.ylabel('Средняя З/П.') plt.title(f'Средняя З/П по городам.') plt.show()
plot_locations() |
Рисунок 4 – Третий график
Вывод:
В ходе выполнения лабораторной работы выполнены небольшие запросы к базе данных средствами языка Python. По полученным данным построены графики в соответствии с заданием по вариантам. Кроме того, функции в которых происходят запросы и построение графиков принимают параметры, позволяющие строить графики с заданными условиями, то есть для любых чисел в соответствии с заданием 3.2.