Forked from dsibi/Добро пожаловать в самостоятельный проект
Created
November 8, 2022 14:11
-
-
Save legale/c6791743a16213397e4f8c5a1e13e2c2 to your computer and use it in GitHub Desktop.
yandex_python_data_analyst_9_Самостоятельный проект: Музыка
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Вы провели исследование, которое включает важнейшие стадии анализа данных. | |
Применили Python и Pandas и ещё раз отработали связку метод-стадия. | |
Отработали методы предобработки, важной стадии анализа данных. | |
Разобрали процесс подготовки проекта в Jupyter Notebook. Теперь вы можете показать своё исследование кому пожелаете для ознакомления, проверки и развития. | |
Получили опыт PR-исследования данных бизнеса с выводами, понятными широкой аудитории. | |
Теперь вы можете проводить небольшие исследования, отвечающие на простые количественные вопросы. Вы также владеете простыми методами предобработки данных. Работайте с готовыми csv-файлами, доводите их до совершенства и проводите базовый анализ. Теперь у вас есть все необходимые для этого инструменты. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Этап 1. Получение данных | |
Изучим данные, предоставленные сервисом для проекта. | |
Импорт библиотек | |
# <импорт библиотеки pandas> | |
import pandas as pd | |
Прочитаем файл music_project.csv и сохраним его в переменной df. | |
# <чтение файла с данными с сохранением в df> | |
df = pd.read_csv('/datasets/music_project.csv') | |
Получение первых 10 строк таблицы. | |
# <получение первых 10 строк таблицы df> | |
df.head(10) | |
userID Track artist genre City time Day | |
0 FFB692EC Kamigata To Boots The Mass Missile rock Saint-Petersburg 20:28:33 Wednesday | |
1 55204538 Delayed Because of Accident Andreas Rönnberg rock Moscow 14:07:09 Friday | |
2 20EC38 Funiculì funiculà Mario Lanza pop Saint-Petersburg 20:58:07 Wednesday | |
3 A3DD03C9 Dragons in the Sunset Fire + Ice folk Saint-Petersburg 08:37:09 Monday | |
4 E2DC1FAE Soul People Space Echo dance Moscow 08:34:34 Monday | |
5 842029A1 Преданная IMPERVTOR rusrap Saint-Petersburg 13:09:41 Friday | |
6 4CB90AA5 True Roman Messer dance Moscow 13:00:07 Wednesday | |
7 F03E1C1F Feeling This Way Polina Griffith dance Moscow 20:47:49 Wednesday | |
8 8FA1D3BE И вновь продолжается бой NaN ruspop Moscow 09:17:40 Friday | |
9 E772D5C0 Pessimist NaN dance Saint-Petersburg 21:20:49 Wednesday | |
Общая информация о данных таблицы df. | |
# <получение общей информации о данных в таблице | |
df.info() | |
<class 'pandas.core.frame.DataFrame'> | |
RangeIndex: 65079 entries, 0 to 65078 | |
Data columns (total 7 columns): | |
userID 65079 non-null object | |
Track 63848 non-null object | |
artist 57876 non-null object | |
genre 63881 non-null object | |
City 65079 non-null object | |
time 65079 non-null object | |
Day 65079 non-null object | |
dtypes: object(7) | |
memory usage: 3.5+ MB | |
Рассмотрим полученную информацию подробнее. | |
Всего в таблице 7 столбцов, тип данных у каждого столбца - < object >. | |
Подробно разберём, какие в df столбцы и какую информацию они содержат: | |
userID — идентификатор пользователя; | |
Track — название трека; | |
artist — имя исполнителя; | |
genre — название жанра; | |
City — город, в котором происходило прослушивание; | |
time — время, в которое пользователь слушал трек; | |
Day — день недели. | |
Количество значений в столбцах различается. Это говорит о том, что в данных есть <пустые> значения. | |
Выводы | |
Каждая строка таблицы содержит информацию о композициях определённого жанра в определённом исполнении, которые пользователи слушали в одном из городов в определённое время и день недели. Две проблемы, которые нужно решать: пропуски и некачественные названия столбцов. Для проверки рабочих гипотез особенно ценны столбцы time, day и City. Данные из столбца genre позволят узнать самые популярные жанры. | |
Этап 2. Предобработка данных | |
Исключим пропуски, переименуем столбцы, а также проверим данные на наличие дубликатов. | |
Получаем перечень названий столбцов. Какая наблюдается проблема — кроме тех, что уже были названы ранее? | |
# <перечень названий столбцов таблицы df> | |
df.columns | |
Index([' userID', 'Track', 'artist', 'genre', ' City ', 'time', 'Day'], dtype='object') | |
В названиях столбцов есть пробелы, которые могут затруднять доступ к данным. | |
Переименуем столбцы для удобства дальнейшей работы. Проверим результат. | |
# <переименование столбцов> | |
#df.columns = ['userID', 'track_name', 'artist_name', 'genre_name', 'city', 'time', 'weekday'] | |
df.set_axis(['user_id', 'track_name', 'artist_name', 'genre_name', 'city', 'time', 'weekday'], axis = 'columns', inplace = True) | |
# <проверка результатов - перечень названий столбцов> | |
list(df) | |
['user_id', | |
'track_name', | |
'artist_name', | |
'genre_name', | |
'city', | |
'time', | |
'weekday'] | |
Проверим данные на наличие пропусков вызовом набора методов для суммирования пропущенных значений. | |
# <суммарное количество пропусков, выявленных методом isnull() в таблице df> | |
df.isnull().sum() | |
#df.columns[df.isnull().any()] # <названия столбцов с наличием пропусков в таблице df> | |
#df[df.columns[df.isnull().any()]]# <названия столбцов с наличием пропусков в таблице df с выводом данных таблицы> | |
user_id 0 | |
track_name 1231 | |
artist_name 7203 | |
genre_name 1198 | |
city 0 | |
time 0 | |
weekday 0 | |
dtype: int64 | |
Пустые значения свидетельствуют, что для некоторых треков доступна не вся информация. Причины могут быть разные: скажем, не назван конкретный исполнитель народной песни. Хуже, если проблемы с записью данных. Каждый отдельный случай необходимо разобрать и выявить причину. | |
Заменяем пропущенные значения в столбцах с названием трека и исполнителя на строку 'unknown'. После этой операции нужно убедиться, что таблица больше не содержит пропусков. | |
# <замена пропущенных значений в столбце 'track_name' на строку 'unknown' специальным методом замены> | |
df['track_name'] = df['track_name'].fillna('unknown') | |
# <замена пропущенных значений в столбце 'artist_name' на строку 'unknown' специальным методом замены> | |
df['artist_name'] = df['artist_name'].fillna('unknown') | |
# <проверка: вычисление суммарного количества пропусков, выявленных в таблице df> | |
df.isnull().sum() | |
user_id 0 | |
track_name 0 | |
artist_name 0 | |
genre_name 1198 | |
city 0 | |
time 0 | |
weekday 0 | |
dtype: int64 | |
Удаляем в столбце с жанрами пустые значения; убеждаемся, что их больше не осталось. | |
# <удаление пропущенных значений в столбце 'genre_name'> | |
df.dropna(subset=['genre_name'],inplace=True) | |
# <проверка> | |
df.isnull().sum() | |
user_id 0 | |
track_name 0 | |
artist_name 0 | |
genre_name 0 | |
city 0 | |
time 0 | |
weekday 0 | |
dtype: int64 | |
Необходимо установить наличие дубликатов. Если найдутся, удаляем, и проверяем, все ли удалились. | |
# <получение суммарного количества дубликатов в таблице df> | |
df.duplicated().sum() | |
3755 | |
# <удаление всех дубликатов из таблицы df специальным методом> | |
df=df.drop_duplicates().reset_index(drop=True) | |
# <проверка на отсутствие> | |
df.duplicated().sum() | |
0 | |
Дубликаты могли появиться вследствие сбоя в записи данных. Стоит обратить внимание и разобраться с причинами появления такого «информационного мусора». | |
Сохраняем список уникальных значений столбца с жанрами в переменной genres_list. | |
Объявим функцию find_genre() для поиска неявных дубликатов в столбце с жанрами. Например, когда название одного и того же жанра написано разными словами. | |
# <сохранение в переменной genres_list списка уникальных значений, выявленных специальным методом в столбце 'genre_name'> | |
genres_list=df['genre_name'].unique() | |
# <создание функции find_genre()> | |
# функция принимает как параметр строку с названием искомого жанра | |
def find_genre(genre): | |
# в теле объявляется переменная-счётчик, ей присваивается значение 0, | |
count=0 | |
# затем цикл for проходит по списку уникальных значений | |
for i in genres_list: | |
# если очередной элемент списка равен параметру функции, | |
if i == genre: | |
#if len(i) == genre: | |
# то значение счётчика увеличивается на 1 | |
count += 1 | |
# по окончании работы цикла функция возвращает значение счётчика | |
return count | |
Вызов функции find_genre() для поиска различных вариантов названия жанра хип-хоп в таблице. | |
Правильное название — hiphop. Поищем другие варианты: | |
hip | |
hop | |
hip-hop | |
# <вызовом функции find_genre() проверяется наличие варианта 'hip'> | |
find_genre('hip') | |
1 | |
# <проверяется наличие варианта 'hop'> | |
find_genre('hop') | |
0 | |
# <проверяется наличие варианта 'hip-hop'> | |
find_genre('hip-hop') | |
0 | |
Объявим функцию find_hip_hop(), которая заменяет неправильное название этого жанра в столбце 'genre_name' на 'hiphop' и проверяет успешность выполнения замены. | |
Так исправляем все варианты написания, которые выявила проверка. | |
# <создание функции find_hip_hop()> | |
# функция принимает как параметры таблицу df и неверное название | |
def find_hip_hop(df,wrong): | |
# к столбцу 'genre_name' применяется специальный метод, | |
# который заменяет второй параметр на строку 'hiphop' | |
df['genre_name'] = df['genre_name'].replace(wrong, 'hiphop') | |
# результат работы равен подсчитанному методом count() числу значений столбца, | |
# которые равны второму параметру | |
total = df.loc[df.loc[:,'genre_name'] == 'wrong']['genre_name'].count() | |
# функция возвращает результат | |
return total | |
0 | |
# <замена одного неверного варианта на hiphop вызовом функции find_hip_hop()> | |
find_hip_hop(df,'hip') | |
#df['genre_name'] = df['genre_name'].replace('hip', 'hiphop') | |
#total = df.loc[df.loc[:,'genre_name'] == 'hip']['genre_name'].count() | |
#print(total) | |
0 | |
Получаем общую информацию о данных. Убеждаемся, что чистка выполнена успешно. | |
# <получение общей информации о данных таблицы df> | |
df.info() | |
print(genres_list) | |
<class 'pandas.core.frame.DataFrame'> | |
RangeIndex: 60126 entries, 0 to 60125 | |
Data columns (total 7 columns): | |
user_id 60126 non-null object | |
track_name 60126 non-null object | |
artist_name 60126 non-null object | |
genre_name 60126 non-null object | |
city 60126 non-null object | |
time 60126 non-null object | |
weekday 60126 non-null object | |
dtypes: object(7) | |
memory usage: 3.2+ MB | |
['rock' 'pop' 'folk' 'dance' 'rusrap' 'ruspop' 'world' 'electronic' | |
'alternative' 'children' 'rnb' 'hip' 'jazz' 'postrock' 'latin' | |
'classical' 'metal' 'reggae' 'tatar' 'blues' 'instrumental' 'rusrock' | |
'dnb' 'türk' 'post' 'country' 'psychedelic' 'conjazz' 'indie' | |
'posthardcore' 'local' 'avantgarde' 'punk' 'videogame' 'techno' 'house' | |
'christmas' 'melodic' 'caucasian' 'reggaeton' 'soundtrack' 'singer' 'ska' | |
'shanson' 'ambient' 'film' 'western' 'rap' 'beats' "hard'n'heavy" | |
'progmetal' 'minimal' 'contemporary' 'new' 'soul' 'holiday' 'german' | |
'tropical' 'fairytail' 'spiritual' 'urban' 'gospel' 'nujazz' 'folkmetal' | |
'trance' 'miscellaneous' 'anime' 'hardcore' 'progressive' 'chanson' | |
'numetal' 'vocal' 'estrada' 'russian' 'classicmetal' 'dubstep' 'club' | |
'deep' 'southern' 'black' 'folkrock' 'fitness' 'french' 'disco' | |
'religious' 'hiphop' 'drum' 'extrememetal' 'türkçe' 'experimental' 'easy' | |
'metalcore' 'modern' 'argentinetango' 'old' 'breaks' 'eurofolk' | |
'stonerrock' 'industrial' 'funk' 'jpop' 'middle' 'variété' 'other' | |
'adult' 'christian' 'gothic' 'international' 'muslim' 'relax' 'schlager' | |
'caribbean' 'ukrrock' 'nu' 'breakbeat' 'comedy' 'chill' 'newage' | |
'specialty' 'uzbek' 'k-pop' 'balkan' 'chinese' 'meditative' 'dub' 'power' | |
'death' 'grime' 'arabesk' 'romance' 'flamenco' 'leftfield' 'european' | |
'tech' 'newwave' 'dancehall' 'mpb' 'piano' 'top' 'bigroom' 'opera' | |
'celtic' 'tradjazz' 'acoustic' 'epicmetal' 'historisch' 'downbeat' | |
'downtempo' 'africa' 'audiobook' 'jewish' 'sängerportrait' 'deutschrock' | |
'eastern' 'action' 'future' 'electropop' 'folklore' 'bollywood' | |
'marschmusik' 'rnr' 'karaoke' 'indian' 'rancheras' 'электроника' | |
'afrikaans' 'tango' 'rhythm' 'sound' 'deutschspr' 'trip' 'lovers' | |
'choral' 'dancepop' 'podcasts' 'retro' 'smooth' 'mexican' 'brazilian' | |
'ïîï' 'mood' 'surf' 'author' 'gangsta' 'triphop' 'inspirational' 'idm' | |
'ethnic' 'bluegrass' 'broadway' 'animated' 'americana' 'karadeniz' | |
'rockabilly' 'colombian' 'self' 'synthrock' 'sertanejo' 'japanese' | |
'canzone' 'swing' 'lounge' 'sport' 'korean' 'ragga' 'traditional' | |
'gitarre' 'frankreich' 'alternativepunk' 'emo' 'laiko' 'cantopop' | |
'glitch' 'documentary' 'rockalternative' 'thrash' 'hymn' 'oceania' | |
'rockother' 'popeurodance' 'dark' 'vi' 'grunge' 'hardstyle' 'samba' | |
'garage' 'soft' 'art' 'folktronica' 'entehno' 'mediterranean' 'chamber' | |
'cuban' 'taraftar' 'rockindie' 'gypsy' 'hardtechno' 'shoegazing' | |
'skarock' 'bossa' 'salsa' 'latino' 'worldbeat' 'malaysian' 'baile' | |
'ghazal' 'loungeelectronic' 'arabic' 'popelectronic' 'acid' 'kayokyoku' | |
'neoklassik' 'tribal' 'tanzorchester' 'native' 'independent' 'cantautori' | |
'handsup' 'poprussian' 'punjabi' 'synthpop' 'rave' 'französisch' | |
'quebecois' 'speech' 'soulful' 'teen' 'jam' 'ram' 'horror' 'scenic' | |
'orchestral' 'neue' 'roots' 'slow' 'jungle' 'indipop' 'axé' 'fado' | |
'showtunes' 'arena' 'irish' 'mandopop' 'forró' 'popdance' 'dirty' | |
'regional'] | |
Вывод | |
На этапе предобработки в данных обнаружились не только пропуски и проблемы с названиями столбцов, но и всяческие виды дубликатов. Их удаление позволит провести анализ точнее. Поскольку сведения о жанрах важно сохранить для анализа, не просто удаляем все пропущенные значения, но заполним пропущенные имена исполнителей и названия треков. Имена столбцов теперь корректны и удобны для дальнейшей работы. | |
Действительно ли музыку в разных городах слушают по-разному? | |
Была выдвинута гипотеза, что в Москве и Санкт-Петербурге пользователи слушают музыку по-разному. Проверяем это предположение по данным о трёх днях недели — понедельнике, среде и пятнице. | |
Для каждого города устанавливаем количество прослушанных в эти дни композиций с известным жанром, и сравниваем результаты. | |
Группируем данные по городу и вызовом метода count() подсчитываем композиции, для которых известен жанр. | |
# <группировка данных таблицы df по столбцу 'city' и подсчёт количества значений столбца 'genre_name'> | |
df.groupby('city')['genre_name'].count() | |
В Москве прослушиваний больше, чем в Питере, но это не значит, что Москва более активна. У Яндекс.Музыки в целом больше пользователей в Москве, поэтому величины сопоставимы. | |
Сгруппируем данные по дню недели и подсчитаем прослушанные в понедельник, среду и пятницу композиции, для которых известен жанр. | |
# <группировка данных по столбцу 'weekday' и подсчёт количества значений столбца 'genre_name'> | |
df.groupby('weekday')['genre_name'].count() | |
Понедельник и пятница — время для музыки; по средам пользователи немного больше вовлечены в работу. | |
Создаём функцию number_tracks(), которая принимает как параметры таблицу, день недели и название города, а возвращает количество прослушанных композиций, для которых известен жанр. Проверяем количество прослушанных композиций для каждого города и понедельника, затем среды и пятницы. | |
# <создание функции number_tracks()> | |
# объявляется функция с тремя параметрами: df, day, city | |
def number_tracks(df, day, city): | |
# в переменной track_list сохраняются те строки таблицы df, для которых | |
# значение в столбце 'weekday' равно параметру day | |
# и одновременно значение в столбце 'city' равно параметру city | |
track_list=df[(df['weekday']==day) & (df['city']==city)] | |
# в переменной track_list_count сохраняется число значений столбца 'genre_name', | |
# рассчитанное методом count() для таблицы track_list | |
track_list_count = track_list['genre_name'].count() | |
# функция возвращает значение track_list_count | |
return track_list_count | |
# <список композиций для Москвы в понедельник> | |
number_tracks(df, 'Monday', 'Moscow') | |
# <список композиций для Санкт-Петербурга в понедельник> | |
number_tracks(df, 'Monday', 'Saint-Petersburg') | |
# <список композиций для Москвы в среду> | |
number_tracks(df, 'Wednesday', 'Moscow') | |
# <список композиций для Санкт-Петербурга в среду> | |
number_tracks(df, 'Wednesday', 'Saint-Petersburg') | |
# <список композиций для Москвы в пятницу> | |
number_tracks(df, 'Friday', 'Moscow') | |
# <список композиций для Санкт-Петербурга в пятницу> | |
number_tracks(df, 'Friday', 'Saint-Petersburg') | |
Сведём полученную информацию в одну таблицу, где ['city', 'monday', 'wednesday', 'friday'] названия столбцов. | |
# <таблица с полученными данными> | |
data = [['Moscow', 15347, 10865, 15680], | |
['Saint-Petersburg', 5519, 6913, 5802]] | |
columns = ['city','monday','wednesday','friday'] | |
table = pd.DataFrame(data = data, columns = columns) | |
table | |
Вывод | |
Результаты показывают, что относительно среды музыку в Петербурге и Москве слушают «зеркально»: в Москве пики приходятся на понедельник и пятницу, а в среду время прослушивания снижается. Тогда как в Санкт-Петербурге среда — день самого большого интереса к музыке, а в понедельник и пятницу он меньше, причём почти одинаково меньше. | |
Утро понедельника и вечер пятницы — разная музыка или одна и та же? | |
Ищем ответ на вопрос, какие жанры преобладают в разных городах в понедельник утром и в пятницу вечером. Есть предположение, что в понедельник утром пользователи слушают больше бодрящей музыки (например, жанра поп), а вечером пятницы — больше танцевальных (например, электронику). | |
Получим таблицы данных по Москве moscow_general и по Санкт-Петербургу spb_general. | |
# получение таблицы moscow_general из тех строк таблицы df, | |
# для которых значение в столбце 'city' равно 'Moscow' | |
moscow_general=df[df['city'] == 'Moscow'] | |
# <получение таблицы spb_general> | |
spb_general=df[df['city']=='Saint-Petersburg'] | |
Создаём функцию genre_weekday(), которая возвращает список жанров по запрошенному дню недели и времени суток с такого-то часа по такой-то. | |
# объявление функции genre_weekday() с параметрами df, day, time1, time2 | |
def genre_weekday(df, day, time1, time2): | |
# в переменной genre_list сохраняются те строки df, для которых одновременно: | |
# 1) значение в столбце 'weekday' равно параметру day, | |
# 2) значение в столбце 'time' больше time1 и | |
# 3) меньше time2. | |
genre_list=df[(df['weekday']==day) & (df['time']>time1)& (df['time']<=time2)] | |
# в переменной genre_list_sorted сохраняются в порядке убывания | |
# первые 10 значений Series, полученной подсчётом числа значений 'genre_name' | |
# сгруппированной по столбцу 'genre_name' таблицы genre_list | |
genre_list_sorted = genre_list.groupby('genre_name')['genre_name'].count().sort_values(ascending = False).head(10) | |
# функция возвращает значение genre_list_sorted | |
return genre_list_sorted | |
Cравниваем полученные результаты по таблице для Москвы и Санкт-Петербурга в понедельник утром (с 7 до 11) и в пятницу вечером (с 17 до 23). | |
# <вызов функции для утра понедельника в Москве (вместо df таблица moscow_general)> | |
genre_weekday(moscow_general, 'Monday', '07:00:00', '11:00:00') | |
# <вызов функции для утра понедельника в Петербурге (вместо df таблица spb_general)> | |
genre_weekday(spb_general, 'Monday', '07:00:00', '11:00:00') | |
# <вызов функции для вечера пятницы в Москве> | |
genre_weekday(moscow_general, 'Friday', '17:00:00', '23:00:00') | |
# <вызов функции для вечера пятницы в Питере> | |
genre_weekday(spb_general, 'Friday', '17:00:00', '23:00:00') | |
# <вызов функции для вечера пятницы в Питере> | |
genre_weekday(spb_general, 'Friday', '17:00:00', '23:00:00') | |
Популярные жанры в понедельник утром в Питере и Москве оказались похожи: везде, как и предполагалось, популярен поп. Несмотря на это, концовка топ-10 для двух городов различается: в Питере в топ-10 входит джаз и русский рэп, а в Москве жанр world. | |
В конце недели ситуация не меняется. Поп-музыка всё так же на первом месте. Опять разница заметна только в концовке топ-10, где в Питере пятничным вечером тоже присутствует жанр world. | |
Вывод | |
Жанр поп безусловный лидер, а топ-5 в целом не различается в обеих столицах. При этом видно, что концовка списка более «живая»: для каждого города выделяются более характерные жанры, которые действительно меняют свои позиции в зависимости от дня недели и времени. | |
Москва и Питер — две разные столицы, два разных направления в музыке. Правда? | |
Гипотеза: Питер богат своей рэп-культурой, поэтому это направление там слушают чаще, а Москва — город контрастов, но основная масса пользователей слушает попсу. | |
Сгруппируем таблицу moscow_general по жанру, сосчитаем численность композиций каждого жанра методом count(), отсортируем в порядке убывания и сохраним результат в таблице moscow_genres. | |
Просмотрим первые 10 строк этой новой таблицы. | |
# одной строкой: группировка таблицы moscow_general по столбцу 'genre_name', | |
# подсчёт числа значений 'genre_name' в этой группировке методом count(), | |
# сортировка Series в порядке убывания и сохранение в moscow_genres | |
moscow_genres=moscow_general.groupby('genre_name')['genre_name'].count().sort_values(ascending = False) | |
# <просмотр первых 10 строк moscow_genres> | |
moscow_genres.head(10) | |
Сгруппируем таблицу spb_general по жанру, сосчитаем численность композиций каждого жанра методом count(), отсортируем в порядке убывания и сохраним результат в таблице spb_genres. | |
Просматриваем первые 10 строк этой таблицы. Теперь можно сравнивать два города. | |
# <группировка таблицы spb_general, расчёт, сохранение в spb_genres> | |
spb_genres=spb_general.groupby('genre_name')['genre_name'].count().sort_values(ascending=False) | |
# <просмотр первых 10 строк spb_genres> | |
spb_genres.head(10) | |
Вывод | |
В Москве, кроме абсолютно популярного жанра поп, есть направление русской популярной музыки. Значит, что интерес к этому жанру шире. А рэп, вопреки предположению, занимает в обоих городах близкие позиции. | |
Этап 4. Результаты исследования | |
Рабочие гипотезы: | |
музыку в двух городах — Москве и Санкт-Петербурге — слушают в разном режиме; | |
списки десяти самых популярных жанров утром в понедельник и вечером в пятницу имеют характерные отличия; | |
население двух городов предпочитает разные музыкальные жанры. | |
Общие результаты | |
Москва и Петербург сходятся во вкусах: везде преобладает популярная музыка. При этом зависимости предпочтений от дня недели в каждом отдельном городе нет — люди постоянно слушают то, что им нравится. Но между городами в разрезе дней неделей наблюдается зеркальность относительно среды: Москва больше слушает в понедельник и пятницу, а Петербург наоборот - больше в среду, но меньше в понедельник и пятницу. | |
В результате первая гипотеза <подтверждена>, вторая гипотеза <не подтверждена > и третья <не подтверждена >. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Самостоятельный проект — это практическая проверка знаний, приобретённых вами на вводном курсе. Каждый раздел посвящён отдельной стадии анализа данных с экскурсом в основы Python. Ещё эту работу можно добавить в портфолио. Вы начинаете собирать это портфолио прямо сейчас. | |
Проект выполняется в пять этапов: | |
Постановка задачи | |
Получение данных | |
Предобработка данных | |
Анализ данных | |
Оформление результатов | |
Для каждой части описаны шаги выполнения c теоретическим приложением. В Jupyter Notebook эти шаги связаны между собой выводами и результатами. | |
Вы закрепите применение операторов и методов языка Python (и его библиотеки Pandas) на разных стадиях анализа данных. Кроме того, получите первый опыт оформления в Jupyter Notebook проекта, которым можно поделиться. | |
Если возникнут сложности, всегда можно воспользоваться навигацией по пройденным урокам, а также шпаргалками. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Яндекс.Музыка — это крупный продукт с огромным запасом данных для исследований. Команды таких сервисов для поддержания интереса к продукту и привлечения новых пользователей часто проводят исследования про пользователей. Чтобы удержать клиентов и привлечь новых, сделать бренд более узнаваемым, команда сервиса проводит исследования аудитории, и публикует интересные результаты. Например, интересно сравнить тексты, сочинённые нейросетью, с произведениями настоящих рэперов. | |
Есть исследование, которое напоминает наше: о музыкальных предпочтениях в разных городах России. | |
Итак, вопрос вам: как музыка, которая звучит по дороге на работу в понедельник утром, отличается от той, что играет в среду или в конце рабочей недели? Возьмите данные для Москвы и Петербурга. Сравните, что и в каком режиме слушают их жители. | |
План исследования | |
Получение данных. Прочитайте данные, ознакомьтесь с ними. | |
Предобработка данных. Избавьтесь от дубликатов, проблем с названиями столбцов и пропусками. | |
Анализ данных. Ответьте на основные вопросы исследования, подготовьте отчётную таблицу или опишите полученный результат. | |
Подведение итогов. Просмотрите выполненную работу и сформулируйте выводы. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment