Узнайте что не так со строкой 964 вызовите знакомый из вводного курса метод loc
Перейти к содержимому

Узнайте что не так со строкой 964 вызовите знакомый из вводного курса метод loc

  • автор:

Узнайте что не так со строкой 964 вызовите знакомый из вводного курса метод loc

Python — отличный язык для анализа данных, в первую очередь благодаря фантастической экосистеме пакетов Python, ориентированных на данные. Pandas является одним из таких пакетов и значительно упрощает импорт и анализ данных.

Панды предоставляют уникальный метод для извлечения строк из фрейма данных. DataFrame.loc[] — это метод, который принимает только метки индекса и возвращает строку или фрейм данных, если метка индекса существует во фрейме данных вызывающей стороны.

Syntax: pandas.DataFrame.loc[]

Parameters:
Index label: String or list of string of index label of rows

Return type: Data frame or Series depending on parameters

Чтобы загрузить CSV, использованный в коде, нажмите здесь.

Пример № 1: Извлечение одной строки

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

# импорт пакета панд

import pandas as pd

# создание фрейма данных из CSV-файла

data = pd.read_csv( «nba.csv» , index_col = «Name» )

# извлечение строки методом loc

first = data.loc[ «Avery Bradley» ]

second = data.loc[ «R.J. Hunter» ]

print (first, «\n\n\n» , second)

Выход:
Как показано на выходном изображении, были возвращены две серии, так как оба раза был только один параметр.

Пример №2: несколько параметров

В этом примере столбец Имя создается как столбец индекса, а затем две отдельные строки извлекаются одновременно путем передачи списка в качестве параметра.

# импорт пакета панд

import pandas as pd

# создание фрейма данных из CSV-файла

data = pd.read_csv( «nba.csv» , index_col = «Name» )

# извлечение строк методом loc

rows = data.loc[[ «Avery Bradley» , «R.J. Hunter» ]]

# проверка типа данных строк

print ( type (rows))

Выход:
Как показано на выходном изображении, на этот раз тип возвращаемого значения является фреймом данных. Обе строки были извлечены и отображены как новый фрейм данных.

Пример № 3: Извлечение нескольких строк с одинаковым индексом

В этом примере имя команды создается как столбец индекса, а одно имя команды передается методу .loc, чтобы проверить, были ли возвращены все значения с одним и тем же именем команды.

# импорт пакета панд

import pandas as pd

# создание фрейма данных из CSV-файла

data = pd.read_csv( «nba.csv» , index_col = «Team» )

# извлечение строк методом loc

rows = data.loc[ «Utah Jazz» ]

# проверка типа данных строк

print ( type (rows))

Выход:
Как показано на выходном изображении, все строки с именем команды «Юта Джаз» были возвращены в виде фрейма данных.

Пример № 4: извлечение строк между двумя индексными метками

В этом примере передаются две метки индекса строк и возвращаются все строки, попадающие между этими двумя метками индекса (обе метки индекса включены).

# импорт пакета панд

import pandas as pd

# создание фрейма данных из CSV-файла

data = pd.read_csv( «nba.csv» , index_col = «Name» )

# извлечение строк методом loc

rows = data.loc[ «Avery Bradley» : «Isaiah Thomas» ]

# проверка типа данных строк

print ( type (rows))

Выход:
Как показано на выходном изображении, все строки, попадающие между двумя пропущенными метками индекса, возвращаются в форме фрейма данных.

Строки. Функции и методы строк

Итак, о работе со строками мы немного поговорили, теперь поговорим о функциях и методах строк.

Я постарался собрать здесь все строковые методы и функции, но если я что-то забыл — поправляйте.

Базовые операции

Длина строки (функция len)

Доступ по индексу

Как видно из примера, в Python возможен и доступ по отрицательному индексу, при этом отсчет идет от конца строки.

Оператор извлечения среза: [X:Y]. X – начало среза, а Y – окончание;

символ с номером Y в срез не входит. По умолчанию первый индекс равен 0, а второй — длине строки.

Кроме того, можно задать шаг, с которым нужно извлекать срез.

Другие функции и методы строк

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

Поэтому все строковые методы возвращают новую строку, которую потом следует присвоить переменной.

Узнайте что не так со строкой 964 вызовите знакомый из вводного курса метод loc

Время прочтения: 5 мин.

Статья выполнена в виде инструкции с пошаговым прогрессом. Пороговый вход для понимания материала не высокий, но кое-что все же нужно знать:

  • типы данных;
  • вызов библиотек;
  • конструктор для таблиц DataFrame;
  • срезы данных.

Исходные данные:

На входе у нас есть Data Frame с данными о поле (м или ж), возрасте, контактной информацией, а также признаком. Для тех, кто не любит абстрагироваться признак – это ответ на вопрос «Играете ли вы в компьютерные игры?» и он может принимать одно из двух значений (да или нет)

Шаг 1. Знакомство с данными

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

Выведем первые строки методом head():

Посмотрим сводную информацию методом info():

Метод info() дает много информации, из которой мы узнаем, что в таблице: 20 строк, 4 столбца, видим типы данных для каждого столбца и количество не нулевых значений.

Шаг 2. Переименование столбцов

Является необязательным шагом, но он делает дальнейшие действия более удобными, а внешний вид приятным. Обычной рекомендацией для названия столбцов является: применение латиницы в названии, нижний регистр, а также отсутствие пропусков в имени столбца (заменяется на символ «_»). Для переименования столбцов применим метод set_axis():

Шаг 3. Пропуски данных

В зависимости от решаемых задач, пропущенные значения могут быть либо удалены методом dropna() (может быть удален как столбец, в котором есть хоть одно пропущенное значение, так и строка).

  • dropna() – удаление строк, где есть пропущенные значения.
  • dropna(subset=[‘col1’, ‘col2’], inplace=True) – удаление строк, где есть пропущенные значения в определенных столбцах (subset).
  • dropna(axis=’col1′, inplace=True) – для удаления столбцов с пропущенными значениями.

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

Удалим все строки, в которых пропущено значение в столбце ‘tag’ методом dropna():

Заменим пропущенный возраст ‘age’, на средний возраст, характерный для определенного пола с определенным признаком, но перед этим проверим какие уникальные значения принимаются в данном столбце. Затем применим метод replace() к значениям ‘None’ и заменим их на NaN:

Выведем на экран срез данных с пропущенными значениями в столбце ‘age’ применив метод isnull():

Заменим пропущенные значения методом fillna() на средний возраст играющих в компьютерные игры мужчин (пропущенные значения соответствуют этим признакам):

Шаг 4. Дубликаты

Для нахождения дубликатов применяется метод duplicated(), совместно с методом sum() можно определить количество дубликатов.

Для удаления дубликатов используем методом следующую конструкцию:

Метод reset_index() необходим для изменения индексации, так как drop_duplicates() вместе со строками удаляет и их индексы.

Проверим наличие дубликатов:

Удалим дубликаты и проверим результат:

Шаг 5. Изменение типов данных

Проверим как сейчас выглядят наши данные. Для просмотра типа данных воспользуемся атрибутом dtypes:

Для того, чтобы они стали более «нарядными», нужно изменить тип данных в столбцах ‘age’ и ‘phone_num’ на int.

Для перевода значений формата string в числовой формат применяется метод библиотеки Pandas to_numeric(). От значения errors метода to_numeric(), зависят действия при работе с некорректным значением:

  • errors=’raise’ — выдается ошибка, операция прерывается;
  • errors=’coerce’ — некорректные значения заменяются на NaN;
  • errors=’ignore’ — некорректные значения игнорируются, но остаются.

Применим метод to_numeric() к столбцу ‘phone_num’:

Для того, чтобы перевести данные в нужный тип, применяется метод astype():

При вызове метода была получена ошибка:

Она возникает, когда в столбце есть данные, принимающие значения NaN. Решением может быть или замена NaN на 0, или на NA. Заменим на NA и поменяем типы данных в нужных столбцах:

Посмотрим на достигнутый результат:

Можно считать задачу решенной, данные подготовлены к дальнейшему анализу.

Похожие публикации:

  1. Как нарисовать человека из гача лайф
  2. Как настроить айфон через айтюнс
  3. Как настроить детский режим в гугл хром
  4. Как настроить микрофон в смартфоне

dsibi / 1. Анализ данных продолжается здесь

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

Данные исследуют в четыре стадии:
Получение данных и ознакомление с ними
Предподготовка данных
Анализ данных
Оформление результатов исследования
В этой теме мы начнём с первой стадии. В получении данных и ознакомлении с ними важную роль выполняет библиотека Pandas.
Чему вы научитесь
Познакомитесь с библиотекой Pandas и её базовыми методами: чтением файла, выводом данных на экран, получением сводной информации и запросом значений из определённых ячеек таблицы.
Сколько времени это займёт
2 часа = 6 уроков от 2 до 30 минут.
Постановка задачи
Решим задачу из реальной практики сервиса Яндекс.Музыка: исследовать предпочтения пользователей и ответить на вопрос, целесообразна ли интеграция двух сервисов — Музыки и Радио.

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

Мы готовим к запуску новый релиз, где соединим вместе приложения Музыка и Радио. Нам важно понимать, как пользователи отреагируют на такое новшество. Для этого мы оцениваем на небольшом количестве пользователей, насколько им понравилась возможность быстрого доступа к Радио.
Каждая компания по-разному оценивает реакцию пользователя на нововведения. Продуктовые исследования в нашем сервисе показали, что среднее время прослушивания лучше всего отражает лояльность пользователей.
Метрика удовлетворенности пользователя сервисом называется happiness. В Яндекс.Музыке метрика happiness равна среднему времени прослушивания треков. Чем выше этот показатель, тем больше доволен пользователь.
image
Есть и другие метрики, которые помогают ответить на вопрос: «Как дела у нашего продукта?»
Если метрика happiness в эксперименте повысится, команда примет решение добавить Радио всем пользователям.
Ваша задача как аналитика Яндекс.Музыки определить текущее значение метрики happiness. Вы пройдёте все стадии – от знакомства с данными до решения бизнес-задачи.

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

Вот так выглядят наши данные на этапе знакомства:
image
Этот хаос нужно превратить в аккуратную табличку, поддающуюся обработке. Для такой задачи подойдёт и Excel, но лучше использовать профильный инструмент — программную библиотеку Pandas.
Библиотеки – это наборы готовых методов для решения распространённых задач. Из того, что есть в Python, для операций с таблицами чаще всего применяют Pandas. Название — от сокращения panel data (англ. «панельные данные») — пришло из терминологии применяемого в экономике панельного анализа, который изучает изменение определённого признака у определённого объекта во времени (например, уровень бедности в Бразилии во второй половине 20 века). Библиотека Pandas оказалась таким универсальным инструментом, что годится для исследования любых данных, которые вообще можно собрать в таблицу.
Почему библиотека Pandas такая крутая и популярная? У неё богатейшие возможности:
Готовые методы для всяческих манипуляций с таблицами: добавления, удаления, преобразования, агрегирования данных;
Одновременная обработка данных из разных файлов;
Готовые методы для операций с пропущенными значениями, выявления и устранения проблемных данных;
Использование данных в самых разных форматах.
Кроме того, вы всегда можете обратиться к хорошо подготовленной документации и активному комьюнити.
Инструменты библиотеки становятся доступны, когда мы вызываем её командой import.
import pandas
Библиотека хранится в переменной, через которую можно вызвать её методы. В сообществе принято давать ей короткое имя pd.
import pandas as pd
Эта команда означает «импортируй библиотеку Pandas как pd».
У нас есть набор данных, который нужно превратить в таблицу. Это делается вызовом конструктора DataFrame().
Конструктор принимает два аргумента – список данных и названия столбцов, которые должны быть в таблице. Например, если информация о столицах разных стран хранится в переменной atlas:
atlas = [
[‘Франция’,’Париж’],
[‘Россия’,’Москва’],
[‘Китай’,’Пекин’],
[‘Мексика’,’Мехико’],
[‘Египет’,’Каир’]
]
и нужно построить таблицу из двух столбцов country и capital,
geography = [‘country’, ‘capital’]
синтаксис вызова конструктора DataFrame() выглядит так:
world_map = pd.DataFrame(data = atlas , columns = geography)
image
Обратите внимание, что DataFrame() – это конструктор библиотеки Pandas, поэтому перед именем конструктора стоит обращение к переменной, в которой библиотека хранится – pd.DataFrame().
atlas = [
[‘Франция’,’Париж’],
[‘Россия’,’Москва’],
[‘Китай’,’Пекин’],
[‘Мексика’,’Мехико’],
[‘Египет’,’Каир’],
]
geography = [‘country’, ‘capital’]
world_map = pd.DataFrame(data = atlas , columns = geography) # таблица сохраняется в переменной с произвольно выбранным именем world_map
print(world_map) # вывод на экран
COUNTRY CAPITAL
0 Франция Париж
1 Россия Москва
2 Китай Пекин
3 Мексика Мехико
4 Египет Каир
В результате простой список пар страна-столица превратился в таблицу с индексами и именованными столбцами. Давайте создадим таблицу с данными о ваших музыкальных предпочтениях.
TASK_1_4
Получите доступ к библиотеке Pandas, используйте имя переменной pd.
SOLUTION
import pandas as pd
TASK_2_4
Создайте список music с 5 парами «имя вашего любимого исполнителя — название его песни». Пример такого списка — atlas из теоретического введения к этому уроку.
import pandas as pd
SOLUTION
import pandas as pd
music=[[‘Меладзе’,’Она была’],
[‘Билан’,’Тоска’],
[‘Пресняков’,’Стюардесса’],
[‘Тальков’,’Чистые пруды’],
[‘Розенбаум’,’Брат мой’],
]
TASK_3_4
Создайте список entries с названиями для двух столбцов — artist и track (здесь эти английские слова употребляются в значении «исполнитель» и «композиция»).
SOLUTION
import pandas as pd
music=[[‘Меладзе’,’Она была’],
[‘Билан’,’Тоска’],
[‘Пресняков’,’Стюардесса’],
[‘Тальков’,’Чистые пруды’],
[‘Розенбаум’,’Брат мой’],
]
entries=[‘artist’,’track’]
TASK_4_4
Используя конструктор DataFrame(), создайте таблицу из списка ваших любимых исполнителей music и списка столбцов entries. Сохраните таблицу в переменной playlist и выведите эту сборную таблицу на экран.
SOLUTION
import pandas as pd
music=[[‘Меладзе’,’Она была’],
[‘Билан’,’Тоска’],
[‘Пресняков’,’Стюардесса’],
[‘Тальков’,’Чистые пруды’],
[‘Розенбаум’,’Брат мой’],
]
entries=[‘artist’,’track’]
playlist=pd.DataFrame(data=music, columns=entries)
print (playlist)

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

У вас есть набор данных. Чтобы начать работу с ним, данные нужно прочитать. Давайте разберёмся, как это сделать.
Знакомому формату электронной таблицы Excel в Pandas соответствует структура данных DataFrame. Аналитики обычно называют такие объекты просто DataFrame.
В рабочей практике вы столкнётесь с тем, что данные хранят в файлах разных форматов. Из них самый распространённый – CSV (от англ. Comma-Separated Values, «значения, разделённые запятой»). Каждая строка такого файла представляет собой одну строку таблицы, где данные разделены запятыми. В первой строке собраны заголовки столбцов (если они есть).
Посмотрите, как одинаковые данные выглядят в Excel (снизу) и CSV (сверху):
image
Файлы CSV удобнее всего открывать вызовом метода read_csv() из библиотеки Pandas.
import pandas as pd
df = pd.read_csv(‘music_log.csv’) # аргумент — путь к файлу
Обратите внимание, что содержимое файла CSV сохраняется в переменной df. Это имя, которое будет встречаться постоянно — общепринятое сокращение от DataFrame.
Теперь все данные из файла можно напечатать на экране командой print(df), но это не всегда нужно делать — не исключено, что таблица огромна и неудобна для изучения. Для знакомства с данными запрашивают несколько строк из начала или конца таблицы, вызывая специальные методы head() и tail(). По умолчанию head() возвращает первые 5 строк набора данных, а метод tail() – последние 5 строк. Когда нужно не 5, количество строк передаётся этим методам как аргумент. Например, head(10) вернёт первые 10 строк. Давайте возьмёмся за поставленную менеджером задачу и откроем файл с данными сервиса Яндекс.Музыка. Получим первый десяток строк этой обширной таблицы:
print(df.head(10))
USER_ID TOTAL PLAY ARTIST GENRE TRACK
0 BF6EA5AF 92.851388 Marina Rei pop Musica
1 FB1E568E 282.981000 Stive Morgan ambient Love Planet
2 FB1E568E 282.981000 Stive Morgan ambient Love Planet
3 EF15C7BA 8.966000 NaN dance Loving Every Minute
4 82F52E69 193.776327 Rixton pop Me And My Broken Heart
5 4166D680 3.007000 Henry Hall & His Gleneagles Hotel Band jazz Home
6 F4F5677 0.100000 NaN classicmetal NaN
7 386FE1ED 211.880000 NaN electronic Riviera
8 A5E0D927 3.161000 Andrew Paul Woodworth pop The Name of This Next Song Is Called
9 E9E8A0CA 274.390000 Pillar Point indie Dove
TASK_1_2
Прочитайте файл music_log.csv и сохраните его в переменной df. Сохраните первые 5 строк с данными из music_log.csv в переменной music_head и выведите значение переменной на экран.
SOLUTION
#
import pandas as pd
df=pd.read_csv(‘music_log.csv’)
music_head = df[:5]
print(music_head.head())
TASK_2_2
Прочитайте файл music_log.csv и сохраните его в переменной df. Сохраните последние 10 строк с данными из music_log.csv в переменной music_tail и выведите значение переменной на экран.
SOLUTION
import pandas as pd
df=pd.read_csv(‘music_log.csv’)
music_tail = df[-10:]
print(music_tail.tail(10))

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

Таблица, которую мы получили, хранится в структуре данных DataFrame. Давайте подробно разберём, из чего состоит этот объект и какие операции с ним можно выполнять.
image
DataFrame — это двумерная структура данных Pandas, где у каждого элемента есть две координаты: по строке и по столбцу.
image
Вы видите две оси, которые формируют объект DataFrame. Первая ось называется индексы, вторая ось — столбцы. По умолчанию индексация в DataFrame начинается с нуля.
Каждая строка — это одно наблюдение, запись об объекте исследования. А столбцы — признаки объектов. В нашем случае одна строка — это одно действие одного пользователя. Прослушивание такой-то композиции в исполнении такой-то группы в течение такого-то времени.
Для лучшего понимания данных полезно получить доступ к их описанию. Это либо документация со сведениями о содержании каждого столбца, либо – не самый лучший вариант – рассказ человека, который предоставил вам эту информацию. Сейчас документация выглядит так:
user_id — содержит информацию об уникальном идентификаторе пользователя;
total play — сколько секунд пользователь слушал трек;
Artist — имя исполнителя;
genre — жанр (рок, поп, электронная музыка, классическая и др.);
track — название трека.
Такое описание поможет нам ставить себе корректные задачи.
У DataFrame есть неотъемлемые свойства, значения которых можно запросить. Они называются атрибуты. Например, атрибут columns содержит информацию о названиях столбцов в наборе данных.
print(df.columns)
image
В данном случае атрибут columns вернул список названий столбцов и сообщил, что каждое из них имеет тип данных object.
Вообще типы данных могут быть разные. Для просмотра типа данных каждого столбца лучше всего использовать атрибут dtypes.
print(df.dtypes)
image
Типы данных, о которых сообщают нам атрибуты — это типы данных библиотеки Pandas. Каждому из них соответствует определённый тип данных языка Python.
Так, для int таким «двойником» в Pandas будет int64. Тип данных object используется, когда данные не подходят ни под одну категорию или соответствуют в Python типу «строка». Вот таблица соответствия типов данных Pandas и Python:
PANDAS DTYPE PYTHON TYPE ЗНАЧЕНИЕ
object str Строка
int64 int Целые числа
float64 float Вещественные числа
bool bool Логический тип данных
О размерах таблицы с данными сообщает её атрибут shape. В результате получается кортеж (неизменяемый список) из двух чисел: первое – количество строк, второе – количество столбцов.
print(df.shape)
image
В таблице 67963 строк (наблюдений) и 5 столбцов.
Кортеж – одномерная неизменяемая последовательность. Это структура данных, похожая на список, её тоже можно сохранять в переменной. Например, кортеж artist содержит имена исполнителей:
artist = (‘Queen’, ‘Led Zeppelin’, ‘Scorpions’)
Но если мы попытаемся изменить элемент кортежа, то Python вернёт ошибку:
artist[0] = ‘Spice Girls’
—————————————————————————
TypeError Traceback (most recent call last)
in ()
—-> 1 artist[0] = ‘Spice Girls’
TypeError: ‘tuple’ object does not support item assignment
Можно получить информацию как обо всём кортеже, так и об отдельных его элементах:
print(artist)
(‘Queen’, ‘Led Zeppelin’, ‘Scorpions’)
print(artist[0])
‘Queen’
Кортеж нужен для хранения и чтения данных, которые лучше не изменять. Он похож на текстовый документ, защищённый от редактирования.
Всю информацию, которую предоставляют разные атрибуты DataFrame, можно получить вызовом одного-единственного метода info(). Изучив результаты, которые этот метод возвращает, аналитик выбирает тактику дальнейшей работы с таблицей.
df.info()
RangeIndex: 67963 entries, 0 to 67962
Data columns (total 5 columns):
user_id 67963 non-null object
total play 67963 non-null float64
Artist 60157 non-null object
genre 65223 non-null object
track 65368 non-null object
dtypes: float64(1), object(4)
memory usage: 2.6+ MB
image
Например, здесь в разных столбцах разное количество элементов с определёнными значениями (non-null). Следовательно, в таблице есть пропущенные значения (null). Прежде чем анализировать такие данные, их нужно обработать. Это одна из самых интересных задач аналитика, и мы поговорим о ней подробнее в следующей теме.
TASK_1_4
Прочитайте файл music_log.csv и сохраните его в переменной df. Создайте переменную shape_table и сохраните в ней размеры таблицы music_log.csv. Напечатайте на экране размер таблицы в таком виде:
Размер таблицы: .
SOLUTION
import pandas as pd
df=pd.read_csv(‘music_log.csv’)
shape_table=df.shape
print(‘Размер таблицы:’, shape_table)
TASK_2_4
Сколько наблюдений в наборе данных? В переменной shape_table хранится кортеж. Его первый элемент — количество наблюдений, который надо сохранить в переменной observations_table (не забывайте, что индексация элементов идёт с 0). Напечатайте на экране ответ в таком виде:
Количество наблюдений: .
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
shape_table = df.shape
observations_table = shape_table [0]
print(‘Количество наблюдений:’, observations_table)
TASK_3_4
Найдите в информации, которую вернул метод info(), число наблюдений. Вручную присвойте это число как значение переменной observations_info_table.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
df.info()
observations_info_table = 67963
TASK_4_4
Вы ещё не запутались? Давайте осмотримся и заодно вспомним условные конструкции.
Поскольку в ходе работы аналитик объявляет разные переменные и сохраняет в них добытую разными способами информацию, запутаться очень легко. Именно поэтому необходимо проверять себя и текущие результаты. Сравните полученные результаты в переменных observations_info_table и observations_table. Если значения переменных совпадают, то выведите количество наблюдений и сообщение:
«Решение верно, количество наблюдений равно», observations_table
Если значения переменных не совпадают, то выведите сообщение:
«Решение неверно, проверьте ещё раз!»
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
observations_info_table = df.shape[0]
observations_table = 67963
if observations_info_table == observations_table:
print(«Решение верно, количество наблюдений равно», observations_table)
else:
print(«Решение неверно, проверьте ещё раз!», observations_table)

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

Сейчас мы, наконец, попробуем получить данные, которые понадобятся непосредственно для выполнения задачи, поставленной менеджером Яндекс.Музыки. Для этого надо уметь запрашивать информацию из определённых ячеек таблицы.
К каждой ячейке с данными в DataFrame можно обратиться по её индексу и названию столбца. Мы можем получать различные срезы данных в зависимости от того, какой запрос к DataFrame мы сформулируем. Этот процесс называется индексация. Для DataFrame она проводится разными способами.
Атрибут loc[строка, столбец] даёт доступ к элементу по строке и столбцу.
image
ВИД РЕАЛИЗАЦИЯ
Одна ячейка .loc[7, ‘genre’]
Один столбец .loc[:, ‘genre’]
Несколько столбцов .loc[:, [‘genre’, ‘Artist’]]
Несколько столбцов подряд (срез) .loc[:, ‘user_id’: ‘genre’]
Одна строка .loc[1]
Все строки, начиная с заданной .loc[1:]
Все строки до заданной .loc[:3]
Несколько строк подряд (срез) .loc[2:5]
image image
Также вы могли заметить, что запрос к атрибуту loc[] использует квадратные скобки, это напоминает списки в Python. Индексация здесь очень похожа на индексацию списков.
Вспомните, как вы играли в «Морской бой» на уроках. Для победы недостаточно просто стрелять куда попало — нужно обдумывать ситуацию на поле противника, чтобы бить в цель как можно точнее.
Посмотрите на поле для игры, оно подобно DataFrame: есть столбцы с буквенными обозначениями и ось индексов. Обратите внимание на разницу в индексах — в DataFrame они от 0 до 9.
image
import pandas as pd
data = [[0,0,0,0,0,0,0,0,0,0],
[0,’-‘,’-‘,’-‘,0,0,0,0,0,0],
[0,’-‘,’X’,’-‘,0,0,’X’,’X’,’X’,’X’],
[0,’-‘,’X’,’-‘,0,0,0,0,0,0],
[0,’-‘,’-‘,’-‘,0,0,0,0,0,0],
[0,0,’-‘,0,0,0,0,0,’X’,0],
[0,’-‘,’X’,’X’,0,0,0,0,0,0],
[0,0,’-‘,’-‘,0,0,0,0,0,0],
[0,0,0,0,’-‘,’X’,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0]]
columns = [‘А’,’Б’,’В’,’Г’,’Д’,’Е’,’Ж’,’З’,’И’,’К’]
battle = pd.DataFrame(data = data, columns = columns)
print(battle)
А Б В Г Д Е Ж З И К
0 0 0 0 0 0 0 0 0 0 0
1 0 — — — 0 0 0 0 0 0
2 0 — X — 0 0 X X X X
3 0 — X — 0 0 0 0 0 0
4 0 — — — 0 0 0 0 0 0
5 0 0 — 0 0 0 0 0 X 0
6 0 — X X 0 0 0 0 0 0
7 0 0 — — 0 0 0 0 0 0
8 0 0 0 0 — X 0 0 0 0
9 0 0 0 0 0 0 0 0 0 0
Ячейки DataFrame со значением 0 обозначают пустую клетку. Информация в ячейке меняется на X, если игрок выстрелил и попал в корабль противника, а если не попал, то меняется на прочерк.
Давайте исследуем текущую ситуацию на поле. Просмотрим столбец ‘В’ и убедимся, что там уже началась атака на корабль:
print(battle.loc[:,’В’])
0 0
1 —
2 X
3 X
4 —
5 —
6 X
7 —
8 0
9 0
Name: В, dtype: object
Действительно, атака уже началась в 6-ой строке, но корабль ещё не убит, а выстрелы в ячейки сверху и снизу кончились промахом. Просмотрим 6-ую строку и узнаем расположение корабля.
print(battle.loc[6])
А 0
Б —
В X
Г X
Д 0
Е 0
Ж 0
З 0
И 0
К 0
Name: 6, dtype: object
Корабль ориентирован по горизонтали, по нему произведено два удачных выстрела, которые пришлись на столбцы В и Г. Нужно оценить ситуацию вокруг корабля. Для этого просмотрим строки с 5 по 7.
print(battle.loc[5:7])
А Б В Г Д Е Ж З И К
5 0 0 — 0 0 0 0 0 X 0
6 0 — X X 0 0 0 0 0 0
7 0 0 — — 0 0 0 0 0 0
Очевидно, что следующий выстрел нужно сделать по координате 6Д. Ура, корабль убит!
Теперь мы хотим найти второй трёхпалубный корабль. Оценим, где вероятнее всего он может располагаться. Для этого просмотрим две половины игрового поля. Срез из столбцов от А до Д даст возможность вывести левую часть таблицы:
print(battle.loc[:,’А’:’Д’])
А Б В Г Д
0 0 0 0 0 0
1 0 — — — 0
2 0 — X — 0
3 0 — X — 0
4 0 — — — 0
5 0 0 — 0 0
6 0 — X X 0
7 0 0 — — 0
8 0 0 0 0 —
9 0 0 0 0 0
Такая же операция для столбцов от Е до К покажет правую часть таблицы:
print(battle.loc[:,’Е’:’К’])
Е Ж З И К
0 0 0 0 0 0
1 0 0 0 0 0
2 0 X X X X
3 0 0 0 0 0
4 0 0 0 0 0
5 0 0 0 X 0
6 0 0 0 0 0
7 0 0 0 0 0
8 X 0 0 0 0
9 0 0 0 0 0
Важное замечание: когда мы используем срезы в списках, то конец среза не включается в результат. А вот атрибут .loc[] тем и выделяется, что включает и начало, и конец среза.
Например, есть список исполнителей:
artist = [‘Marina Rei’, ‘Stive Morgan’,’Rixton’,’Henry Hall & His Gleneagles Hotel Band’, ‘Andrew Paul Woodworth’, ‘Pillar Point’,’Steve Campbell’,’David Civera’,’Lumipa Beats’, ‘Henning Wehland’]
Элементы с 2 по 4 получают запросом:
print(artist[2:5])
[‘Rixton’, ‘Henry Hall & His Gleneagles Hotel Band’, ‘Andrew Paul Woodworth’]
Последним в запросе указан индекс 5 — именно для того, чтобы в срез попал элемент с индексом 4. Запрос на получение со 2 по 4 строки в таблице будет выглядеть вот так:
print(df.loc[2:4])
USER_ID TOTAL PLAY ARTIST GENRE TRACK
2 FB1E568E 282.981000 Stive Morgan ambient Love Planet
3 EF15C7BA 8.966000 NaN dance Loving Every Minute
4 82F52E69 193.776327 Rixton pop Me And My Broken Heart
Итак, вы видели, как запрашивать один столбец, одну строку, диапазон столбцов и диапазон строк. Это самые ходовые запросы, которые вам предстоит делать как аналитику данных.
На практике чаще применяют сокращённую форму записи для индексации. Но возможности у неё ограничены. Имейте в виду, что она не всегда возвращает те же результаты, что атрибут .loc[] в его полном варианте.
ВИД РЕАЛИЗАЦИЯ СОКРАЩЁННАЯ ЗАПИСЬ
Одна ячейка .loc[7, ‘genre’] —
Один столбец .loc[:, ‘genre’] df[‘genre’]
Несколько столбцов .loc[:, [‘genre’, ‘Artist’]] df [[‘genre’, ‘Artist’]]
Несколько столбцов подряд (срез) .loc[:, ‘user_id’: ‘genre’] —
Одна строка .loc[1] —
Все строки, начиная с заданной .loc[1:] df[1:]
Все строки до заданной .loc[:3] включая 3 df[:3] не включая 3
Несколько строк подряд (срез) .loc[2:5]включая 5 df[2:5] не включая 5
Неприятельский трёхпалубный корабль, скорее всего, на правой половине поля. Это можно предположить, оглядев по очереди оба среза. Аналитики называют такой метод изучения «посмотреть на данные глазами».
На глаз хорошо выбирать направление дальнейших поисков, но так не получишь точных цифр, которые можно включить в отчёт. Надо уметь подсчитать количество определённых значений, например, точных попаданий. В Pandas для этого есть метод count().
Его вызывают и приказывают сосчитать, например, количество ячеек столбца В, где были попадания. Удачный выстрел — это значение «X» в ячейке. Для столбца В таблицы battle такие ячейки отвечают логическому условию battle.loc[:,’В’] == ‘X’. Поскольку в указании, какие именно значения считать, нужен логический оператор, такой доступ к значению ячейки называют логическая индексация.
image
print(battle.loc[battle.loc[:,’В’] == ‘X’][‘В’].count()) # используем метод .count() для подсчёта записей, удовлетворяющих условию в столбце В
3
ВИД РЕАЛИЗАЦИЯ СОКРАЩЁННАЯ ЗАПИСЬ
Все строки, удовлетворяющие условию battle.loc[battle.loc[:,’В’] == ‘X’] battle[battle[‘В’] == ‘X’]
Столбец, удовлетворяющий условию battle.loc[battle.loc[:,’В’] == ‘X’][‘В’] battle[battle[‘В’] == ‘X’][‘В’]
Применение метода battle.loc[battle.loc[:,’В’] == ‘X’][‘В’].count() battle[battle[‘В’] == ‘X’][‘В’].count()
Конечно, писать вызов метода count() для подсчёта попаданий в «морском бою» то же, что стрелять из пушки по воробьям. Но в анализе таблиц на много тысяч строк счётный метод — мощное орудие. Попробуйте в задаче с данными Яндекс.Музыки определить, какой жанр оказался популярнее у пользователей: поп или рок?
TASK_1_4
Получите таблицу, состоящую из столбцов genre и Artist. Сохраните её в переменной genre_fight.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
genre_fight=df.loc[:,[‘genre’, ‘Artist’]]
TASK_2_4
Посчитайте число прослушанных треков в жанре поп. Для этого лучше всего использовать логическое условие genre_fight[‘genre’] == ‘pop’. Сохраните результат в переменной genre_pop. Напечатайте ответ на экране в таком виде:
Число прослушанных треков в жанре поп равно .
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
genre_fight=df.loc[:,[‘genre’, ‘Artist’]]
genre_pop=genre_fight.loc[genre_fight.loc[:,’genre’] == ‘pop’][‘genre’].count()
print(‘Число прослушанных треков в жанре поп равно’, genre_pop)
TASK_3_4
Теперь посчитайте число прослушанных треков в жанре рок. Допишите в код подсчёт, похожий на предыдущий, только с логическим условием df[‘genre’] == ‘rock’. Сохраните результат в переменной genre_rock. Напечатайте ответ на экране в таком виде:
Число прослушанных треков в жанре поп равно . Число прослушанных треков в жанре рок равно .
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
genre_fight=df.loc[:,[‘genre’, ‘Artist’]]
genre_pop=genre_fight.loc[genre_fight.loc[:,’genre’] == ‘pop’][‘genre’].count()
genre_rock=genre_fight.loc[genre_fight.loc[:,’genre’] == ‘rock’][‘genre’].count()
print(‘Число прослушанных треков в жанре поп равно’, genre_pop)
print(‘Число прослушанных треков в жанре рок равно’, genre_rock)
TASK_4_4
Напишите условную конструкцию, которая сравнивает полученные значения и выводит информацию о победителе в этом бою! Если победил жанр рок, то выведите сообщение «Рок победил!», а если победил жанр поп — сообщение «Попса forever!»
Не удаляйте вывод числа прослушанных треков в жанрах поп и рок.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
genre_fight=df.loc[:,[‘genre’, ‘Artist’]]
genre_pop=genre_fight.loc[genre_fight.loc[:,’genre’] == ‘pop’][‘genre’].count()
genre_rock=genre_fight.loc[genre_fight.loc[:,’genre’] == ‘rock’][‘genre’].count()
print(‘Число прослушанных треков в жанре поп равно’, genre_pop)
print(‘Число прослушанных треков в жанре рок равно’, genre_rock)
if genre_pop>genre_rock:
print(‘Попса forever!’)
else:
print(‘Рок победил!’)

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

В таблице, которую мы рассматривали весь прошлый урок, каждый столбец сам по себе — вовсе не структура данных DataFrame. Удивлены? Давайте проверим.
Таблица всё так же имеет тип DataFrame.
image
Но если мы возьмём отдельный столбец таблицы, то он представляет собой совсем иную структуру данных — Series.
image
Давайте разберёмся, что интересного в новом объекте Series.
Series — одномерная таблица, и её элементы можно получить по индексу. Каждый индекс — это номер отдельного наблюдения, и поэтому несколько различных Series вместе составляют DataFrame. В Series хранятся данные одного типа.
image
У каждой Series есть имя (Name), информация о количестве данных в столбце (Length) и тип данных, которые хранятся в ней (dtype).
print(df[‘Artist’])
0 Marina Rei
1 Stive Morgan
2 Stive Morgan
3 NaN
4 Rixton
5 Henry Hall & His Gleneagles Hotel Band
6 NaN
7 NaN
8 Andrew Paul Woodworth
9 Pillar Point
10 Steve Campbell
11 David Civera
12 Lumipa Beats
13 Henning Wehland
14 NaN
15 Пётр Каледин
16 ChinKong
.
67951 Julien Mier
67952 Bierstrassen Cowboys
67953 Flip Grater
67954 Alt & J
67955 TKN
67956 89ers
67957 Steel Pulse
67958 Nadine Coyle
67959 Digital Hero
67960 Red God
67961 Less Chapell
67962 NaN
Name: Artist, Length: 67963, dtype: object
Не все данные в этом столбце Artist относятся к типу object — есть и пропущенные значения NaN. О них мы подробно расскажем в теме, посвящённой «информационному мусору». Вместе с ними длина столбца равна общему числу наблюдений 67963.
Индексация в Series аналогична индексации элементов столбца в DataFrame. Давайте рассмотрим на примере. Сохраним столбец total play в переменной total_play.
total_play = df.loc[:, ‘total play’]
Для получения пятого по индексу элемента укажем 5 в квадратных скобках.
print(total_play[5])
3.007
Если надо получить диапазон ячеек, запросите атрибут loc с границами среза в квадратных скобках.
print(total_play.loc[5:10])
5 3.007
6 0.100
7 211.880
8 3.161
9 274.390
10 8.836
Name: total play, dtype: float64
Вот таблица различных вариантов индексации в Series с сокращённой записью.
ВИД РЕАЛИЗАЦИЯ СОКРАЩЁННАЯ ЗАПИСЬ
Один элемент total_play.loc[7] total_play[7]
Несколько элементов total_play.loc[[5, 7, 10]] total_play[[5, 7, 10]]
Несколько элементов подряд (срез) total_play.loc[5:10] включая 10 total_play[5:10] не включая 10
Все элементы, начиная с заданного total_play.loc[1:] total_play[1:]
Все элементы до заданного total_play.loc[:3] включая 3 total_play[:3] не включая 3
Для Series также возможна логическая индексация. Рассмотрим такой пример — пользователю может не понравиться песня, которая начала играть, и он нажмёт кнопку «Следующий трек». Тогда в таблице сохраняется очень малое время прослушивания — от нуля до нескольких секунд. Вы можете проверить, сколько пользователей в течение нескольких секунд — не более 10 — приняли решение пропустить песню, которая только началась.
Для решения задачи воспользуемся логическим условием total_play
image
print(total_play.loc[total_play
3 8.966000
5 3.007000
6 0.100000
8 3.161000
10 8.836000
11 0.000000
13 2.000000
14 0.000000
15 0.000000
18 0.100000
19 7.000000
24 8.109446
26 0.000000
31 3.253000
33 0.100000
34 0.000000
36 9.200000
39 3.663453
40 0.100000
41 0.100000
42 1.464589
45 0.100000
47 0.100000
49 6.000000
51 0.872000
55 8.443000
63 1.687000
64 3.773000
66 7.670000
68 0.000000
.
67878 0.919000
67880 1.090000
67885 2.000000
67886 4.040000
67887 7.680563
67888 8.578000
67894 2.065000
67896 0.000000
67897 0.100000
67899 3.676000
67900 0.000000
67905 0.000000
67906 3.682000
67907 4.179592
67908 0.000000
67912 0.000000
67916 6.947000
67917 4.000000
67918 0.000000
67923 1.753000
67927 1.954282
67929 0.100000
67932 1.439000
67946 2.101000
67949 0.100000
67950 3.496000
67951 1.318000
67953 2.502000
67956 2.000000
67962 0.100000
Name: total play, Length: 29160, dtype: float64
print(total_play.loc[total_play
29160
Порог в 10 секунд мы выбрали произвольно. Но было бы интересно установить, существует ли на самом деле какое-нибудь пороговое время — длительность воспроизведения композиции, после которого пользователь чаще всего не пропускает трек, а слушает его до конца. Анализ данных позволяет ставить такие задачи и находить на них ответы.
Давайте вернёмся к войне между роком и попсой! Вам предлагается установить, сколько композиций этих жанров слушали не более 5 секунд и определить: зависит ли быстрота принятия решения о пропуске трека от жанра или на это влияют другие причины?
TASK_1_7
Получите таблицу только с жанром rock и сохраните её в переменной rock.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
df[‘genre’] == ‘rock’
rock = df[df[‘genre’] == ‘rock’]
TASK_2_7
Выделим время прослушивания роковых композиций в особую структуру данных. Сохраните столбец ‘total play’ таблицы rock в переменной rock_time.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
df[‘genre’] == ‘rock’
rock = df[df[‘genre’] == ‘rock’]
# Выделим время прослушивания роковых композиций в особую структуру данных
# Сохраним столбец ‘total play’ таблицы rock в переменной rock_time.
rock_time = rock[‘total play’]
TASK_3_7
Обратитесь к новой Series c именем rock_time и посчитайте количество треков жанра рок, пропущенных в течение 5 секунд. Логическим условием укажите rock_time
Количество пропущенных треков жанра рок равно .
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
df[‘genre’] == ‘rock’
rock = df[df[‘genre’] == ‘rock’]
# Выделим время прослушивания роковых композиций в особую структуру данных
# Сохраним столбец ‘total play’ таблицы rock в переменной rock_time.
rock_time = rock[‘total play’]
rock_haters=rock_time.loc[rock_time
print(‘Количество пропущенных треков жанра рок равно’,rock_haters)
TASK_4_7
Выберите из исходной таблицы только строки с жанром ‘pop’ и сохраните эту новую таблицу в переменной pop.
Вывод результата предыдущей задачи закомментируйте.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
#df[‘genre’] == ‘rock’
#rock = df[df[‘genre’] == ‘rock’]
# Выделим время прослушивания роковых композиций в особую структуру данных
# Сохраним столбец ‘total play’ таблицы rock в переменной rock_time.
#rock_time = rock[‘total play’]
#rock_haters=rock_time.loc[rock_time
#print(‘Количество пропущенных треков жанра рок равно’,rock_haters)
df[‘genre’] == ‘pop’
pop = df[df[‘genre’] == ‘pop’]
TASK_5_7
Теперь по аналогии с роком создайте Series, где хранятся только данные о времени воспроизведения композиций в жанре поп. Назовите его pop_time и сохраните в нём данные столбца ‘total play’ из таблицы pop .
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
#df[‘genre’] == ‘rock’
#rock = df[df[‘genre’] == ‘rock’]
# Выделим время прослушивания роковых композиций в особую структуру данных
# Сохраним столбец ‘total play’ таблицы rock в переменной rock_time.
#rock_time = rock[‘total play’]
#rock_haters=rock_time.loc[rock_time
#print(‘Количество пропущенных треков жанра рок равно’,rock_haters)
df[‘genre’] == ‘pop’
pop = df[df[‘genre’] == ‘pop’]
pop_time = pop[‘total play’]
TASK_6_7
Снова по аналогии с роком обратитесь к Series, на сей раз pop_time, чтобы посчитать количество пропущенных в течение 5 секунд треков жанра поп. Используйте условие pop_time
Количество пропущенных треков жанра поп равно .
Вывод данных о роке закомментируйте.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
#df[‘genre’] == ‘rock’
#rock = df[df[‘genre’] == ‘rock’]
# Выделим время прослушивания роковых композиций в особую структуру данных
# Сохраним столбец ‘total play’ таблицы rock в переменной rock_time.
#rock_time = rock[‘total play’]
#rock_haters=rock_time.loc[rock_time
#print(‘Количество пропущенных треков жанра рок равно’,rock_haters)
df[‘genre’] == ‘pop’
pop = df.loc[df[‘genre’] == ‘pop’]
pop_time = pop[‘total play’]
pop_haters=pop_time.loc[pop_time
print(‘Количество пропущенных треков жанра поп равно’,pop_haters)
TASK_7_7
Для обоих жанров посчитайте долю быстро пропущенных пользователями композиций в процентах. Разделите количество треков, которые пользователи пропустили — соответственно rock_haters и pop_haters — на общее количество треков жанра рок и жанра поп.
Общее количество треков жанра равно количеству наблюдений в таблицах rock и pop, т.е. значению атрибута shape[0] этих таблиц.
Результаты сохраните в переменных rock_skip и pop_skip. Выведите значения новых переменных в процентах с точностью до одного знака после запятой в такой форме:
Доля пропущенных композиций жанра рок равна: .
Доля пропущенных композиций жанра поп равна: .
Вывод результата предыдущей задачи закомментируйте.
SOLUTION
import pandas as pd
df = pd.read_csv(‘music_log.csv’)
# Получим таблицу только с жанром rock и сохраним её в переменной rock
df[‘genre’] == ‘rock’
rock = df[df[‘genre’] == ‘rock’]
# Выделим время прослушивания роковых композиций в особую структуру данных
# Сохраним столбец ‘total play’ таблицы rock в переменной rock_time.
rock_time = rock[‘total play’]
# Обратитмся к новой Series c именем rock_time и посчитайте количество треков жанра рок, пропущенных в течение 5 секунд.
rock_haters = rock_time[rock_time
# print(‘Количество пропущенных треков жанра рок равно’, rock_haters)
# Выберем из исходной таблицы только строки с жанром ‘pop’ и сохраним эту новую таблицу в переменной pop.
df[‘genre’] == ‘pop’
pop = df[df[‘genre’] == ‘pop’]
# Теперь по аналогии с роком создайте Series, где хранятся только данные о времени воспроизведения композиций в жанре поп.
pop_time = pop[‘total play’]
#Снова по аналогии с роком обратимся к Series, на сей раз pop_time, чтобы посчитать количество пропущенных в течение 5 секунд треков жанра поп.
pop_haters = pop_time[pop_time
# print(‘Количество пропущенных треков жанра поп равно’, pop_haters)
# Для обоих жанров посчитайте долю быстро пропущенных пользователями композиций в процентах.
df[‘genre’] == ‘rock’
rock = df[df[‘genre’] == ‘rock’]
rock_time = rock[‘total play’]
rock_haters = rock_time[rock_time
df[‘genre’] == ‘pop’
pop = df[df[‘genre’] == ‘pop’]
pop_time = pop[‘total play’]
pop_haters = pop_time[pop_time
rock_skip=rock_haters/rock.shape[0]
print(‘Доля пропущенных композиций жанра рок равна: ‘.format(rock_skip))
pop_skip = pop_haters/pop.shape[0]
print(‘Доля пропущенных композиций жанра поп равна: ‘.format(pop_skip))

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *