Введение
Ручной поиск дубликатов
name count 0 Сырок Мечта 120 1 Молоко Отличное 200 2 Сырок Мечта 125 3 Сырок Дружба 100 4 Сырок Дружба 35
Посчитаем дубликаты в столбце name:
import pandas as pd
df = pd.DataFrame({
'name': ['Сырок Мечта', 'Молоко Отличное', 'Сырок Мечта', 'Сырок Дружба',\
'Сырок Дружба', 'Молоко Вкусное'],
'count': [120, 200, 125, 100, 35, 500]
})
print(df['name'].duplicated().sum())
2
В столбце name есть два дубликата. Попробуем применить метод value_counts(), чтобы посмотреть, какие именно названия повторяются.
import pandas as pd
df = pd.DataFrame({
'name': ['Сырок Мечта', 'Молоко Отличное', 'Сырок Мечта', 'Сырок Дружба',\
'Сырок Дружба', 'Молоко Вкусное'],
'count': [120, 200, 125, 100, 35, 500]
})
print(df['name'].value_counts())
name Сырок Мечта 2 Сырок Дружба 2 Молоко Отличное 1 Молоко Вкусное 1 Name: count, dtype: int64
Итак, повторяются сырок «Мечта» и сырок «Дружба». Из-за этого получается, что информация о количестве товара недостоверна. Когда данных очень много — это легко не заметить и сложно обработать вручную.
Найдём общее количество сырков «Мечта» на складе. Для этого отфильтруем строки таблицы, у которых в столбце name
записано Сырок Мечта
, выберем столбец с количеством count
и найдём сумму методом sum()
:
import pandas as pd
df = pd.DataFrame({
'name': ['Сырок Мечта', 'Молоко Отличное', 'Сырок Мечта', 'Сырок Дружба',\
'Сырок Дружба', 'Молоко Вкусное'],
'count': [120, 200, 125, 100, 35, 500]
})
mechta = df[df['name'] == 'Сырок Мечта']['count'].sum()
print(mechta)
245
Аналогично поступим с сырком «Дружба»:
import pandas as pd
df = pd.DataFrame({
'name': ['Сырок Мечта', 'Молоко Отличное', 'Сырок Мечта', 'Сырок Дружба',\
'Сырок Дружба', 'Молоко Вкусное'],
'count': [120, 200, 125, 100, 35, 500]
})
mechta = df[df['name'] == 'Сырок Мечта']['count'].sum()
druzhba = df[df['name'] == 'Сырок Дружба']['count'].sum()
print(druzhba)
135
Нашли общее количество сырков и сохранили. Теперь удалим строки с дубликатами в столбцеname
из исходной таблицыdf
. Из строк с повторами в столбцеname
будем оставлять первые.
name count 0 Сырок Мечта 120 1 Молоко Отличное 200 3 Сырок Дружба 100 5 Молоко Вкусное 500
Для сравнения, с аргументом'last'
датафрейм выглядел бы следующим образом (обратите внимание на столбецcount
):
import pandas as pd
df = pd.DataFrame({
'name': ['Сырок Мечта', 'Молоко Отличное', 'Сырок Мечта', 'Сырок Дружба',\
'Сырок Дружба', 'Молоко Вкусное'],
'count': [120, 200, 125, 100, 35, 500]
})
mechta = df[df['name'] == 'Сырок Мечта']['count'].sum()
druzhba = df[df['name'] == 'Сырок Дружба']['count'].sum()
df = df.drop_duplicates(subset=['name'], keep='last')
print(df)
name count 1 Молоко Отличное 200 2 Сырок Мечта 125 4 Сырок Дружба 35 5 Молоко Вкусное 500
Для красоты создадим новые индексы со сброшенной нумерацией строк и удалим старые.
С помощью какого метода это можно сделать?
reset_index(drop=True)
Правильно! Метод reset_index() с аргументом drop=True создаст новые индексы и удалит старые.
Итак, сбросим индексы в датафрейме df.
import pandas as pd
df = pd.DataFrame({
'name': ['Сырок Мечта', 'Молоко Отличное', 'Сырок Мечта', 'Сырок Дружба',\
'Сырок Дружба', 'Молоко Вкусное'],
'count': [120, 200, 125, 100, 35, 500]
})
mechta = df[df['name'] == 'Сырок Мечта']['count'].sum()
druzhba = df[df['name'] == 'Сырок Дружба']['count'].sum()
df = df.drop_duplicates(subset=['name'], keep='first')
df = df.reset_index(drop=True)
print(df)
name count 0 Сырок Мечта 120 1 Молоко Отличное 200 2 Сырок Дружба 100 3 Молоко Вкусное 500
Заменим значения в строках с индексами0
(сырок «Мечта») и2
(сырок «Дружба») в столбце count на заранее подсчитанные:
import pandas as pd
df = pd.DataFrame({
'name': ['Сырок Мечта', 'Молоко Отличное', 'Сырок Мечта', 'Сырок Дружба',\
'Сырок Дружба', 'Молоко Вкусное'],
'count': [120, 200, 125, 100, 35, 500]
})
mechta = df[df['name'] == 'Сырок Мечта']['count'].sum()
druzhba = df[df['name'] == 'Сырок Дружба']['count'].sum()
df = df.drop_duplicates(subset=['name'], keep='first')
df = df.reset_index(drop=True)
df.loc[0, 'count'] = mechta
df.loc[2, 'count'] = druzhba
print(df)
name count 0 Сырок Мечта 245 1 Молоко Отличное 200 2 Сырок Дружба 135 3 Молоко Вкусное 500
Лаборатория ручного поиска дубликатов
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
print(stock.head())
\ | id | item | count |
---|---|---|---|
0 | 100480924 | Смартфон Xiaomi Redmi 6A 16GB | 32 |
1 | 100480929 | Смартфон Xiaomi Redmi 6A 16GB | 10 |
2 | 100480938 | Смартфон Samsung Galaxy A30 32GB | 49 |
3 | 100480952 | смартфон Samsung Galaxy A30 32gb | 11 |
4 | 100480959 | Смартфон HUAWEI P30 lite | 5 |
В таблице учёта:
- столбец id с идентификаторами товаров;
- столбец item с полными названиями моделей;
- столбец count, где посчитано количество смартфонов конкретной модели в продаже.
Задача №1
Уже в первых двух строках встречаем дубликат
: названия моделей абсолютно одинаковы, а id
— разные. Получается, что таблица учёта даёт неверное представление о количестве смартфонов Xiaomi Redmi 6A 16GB
: их не 32 и не 10, а целых 42! Что, если такие повторы встречаются в таблице и дальше и самих дубликатов больше? Хорошо бы проанализировать сразу весь набор данных, а не просматривать каждую строку.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
# ваш код здесь
print (stock.duplicated('item').sum())
3
Дубликатов оказалось больше, чем вы успели заметить. Повезло, что строк всего десять и искать повторы в такой таблице недолго.
Задача №2
Примените метод value_counts()
к столбцу item
датафрейма stock
. Результат выведите на экран.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
print (stock.value_counts('item'))
item
Смартфон Xiaomi Redmi 6A 16GB 3
Смартфон HUAWEI P30 lite 2
Смартфон Apple iPhone Xr 64GB 1
Смартфон Apple iPhone Xr 64gb 1
Смартфон Honor 8X 64GB 1
Смартфон Samsung Galaxy A30 32GB 1
смартфон Samsung Galaxy A30 32gb 1
dtype: int64
Час от часу не легче. Ладно Xiaomi... Но ведь и HUAWEI туда же!
Задача №3
Начните собирать данные для новой таблицы уже без дубликатов. Посчитайте количество телефонов Xiaomi Redmi — Смартфон Xiaomi Redmi 6A 16GB
— на складе и сохраните его в переменной xiaomi
. Используйте логическую индексацию и отфильтруйте строки датафрейма, выбор столбца count
и метод sum()
для столбца. Результат выведите на экран.
Если вы не помните, как работать с логической индексацией, ничего страшного. Можно вернуться ко второй теме этого спринта и повторить изученный материал.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
# подсчитайте количество телефонов Xiaomi Redmi
xiaomi = stock[stock['item']=='Смартфон Xiaomi Redmi 6A 16GB']['count'].sum()
# выведите значение xiaomi на экран
print (xiaomi)
44
На складе всего 44 смартфона Xiaomi. А что же с HUAWEI?
Задача №4
Аналогичным образом найдите количество смартфонов HUAWEI (это Смартфон HUAWEI P30 lite
) и сохраните его в переменной huawei
. Результат выведите на экран.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
xiaomi = stock[stock['item'] == 'Смартфон Xiaomi Redmi 6A 16GB']['count'].sum()
# напишите ваш код здесь
huawei = stock[stock['item'] == 'Смартфон HUAWEI P30 lite']['count'].sum()
# выведите значение переменной huawei на экран
print (huawei)
38
На складе 38 смартфонов HUAWEI. Хм, это немного меньше, чем у Xiaomi…
Задача №5
«Перезапишите» stock
и удалите из самого датафрейма строки с дубликатами в столбце item
, оставив только первые вхождения: будем считать, что верные идентификаторы товаров для «дубликатов» встречаются первыми в таблице. Решая задание, используйте метод для удаления дубликатов. Когда будете выполнять операцию, не забудьте про параметры subset
и keep
. После не сбрасывайте индексы и выведите на экран всю таблицу.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
xiaomi = stock[stock['item'] == 'Смартфон Xiaomi Redmi 6A 16GB']['count'].sum()
huawei = stock[stock['item'] == 'Смартфон HUAWEI P30 lite']['count'].sum()
# удалите строки с дубликатами в столбце 'item'
stock = stock.drop_duplicates(subset=['item'], keep='first')
# выведите всю таблицу stock на экран
print (stock)
id item count
0 100480924 Смартфон Xiaomi Redmi 6A 16GB 32
2 100480938 Смартфон Samsung Galaxy A30 32GB 49
3 100480952 смартфон Samsung Galaxy A30 32gb 11
4 100480959 Смартфон HUAWEI P30 lite 5
5 100480975 Смартфон Apple iPhone Xr 64gb 10
6 100480988 Смартфон Honor 8X 64GB 64
9 100481020 Смартфон Apple iPhone Xr 64GB 19
Дубликатов больше нет.
Задача №6
В столбце item
сбилась нумерация после того, как в нём удалили строки с дубликатами. Допустим, в этом случае в номерах строк нет особого смысла — мы хотим восстановить нумерацию путём сброса пропусков в ней. Восстановите индексы строк методом reset_index()
c параметром drop
, равным True
. Выведите на экран таблицу.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
xiaomi = stock[stock['item'] == 'Смартфон Xiaomi Redmi 6A 16GB']['count'].sum()
huawei = stock[stock['item'] == 'Смартфон HUAWEI P30 lite']['count'].sum()
stock = stock.drop_duplicates(subset=['item'], keep='first')
# восстановите индексы с помощью reset_index(drop=True)
stock = stock.reset_index(drop=True)
# выведите stock на экран
print (stock)
id item count
0 100480924 Смартфон Xiaomi Redmi 6A 16GB 32
1 100480938 Смартфон Samsung Galaxy A30 32GB 49
2 100480952 смартфон Samsung Galaxy A30 32gb 11
3 100480959 Смартфон HUAWEI P30 lite 5
4 100480975 Смартфон Apple iPhone Xr 64gb 10
5 100480988 Смартфон Honor 8X 64GB 64
6 100481020 Смартфон Apple iPhone Xr 64GB 19
Отлично, номера строк восстановлены!
Задача №7
Вернитесь к столбцу count
в датафрейме stock
. Из нулевой строки и столбца запишите в ячейку с количеством телефонов Xiaomi Redmi 6A 16GB
обновлённое количество телефонов Xiaomi. Ранее вы сохранили это значение в переменной xiaomi
. Выведите таблицу stock
на экран и изучите результат.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
xiaomi = stock[stock['item'] == 'Смартфон Xiaomi Redmi 6A 16GB']['count'].sum()
huawei = stock[stock['item'] == 'Смартфон HUAWEI P30 lite']['count'].sum()
stock = stock.drop_duplicates(subset=['item'], keep='first')
stock = stock.reset_index(drop=True)
# замените значение в ячейке с количеством смартфонов Xiaomi
stock.loc[0,'count'] = xiaomi
# выведите таблицу stock на экран
print (stock)
id item count
0 100480924 Смартфон Xiaomi Redmi 6A 16GB 44
1 100480938 Смартфон Samsung Galaxy A30 32GB 49
2 100480952 смартфон Samsung Galaxy A30 32gb 11
3 100480959 Смартфон HUAWEI P30 lite 5
4 100480975 Смартфон Apple iPhone Xr 64gb 10
5 100480988 Смартфон Honor 8X 64GB 64
6 100481020 Смартфон Apple iPhone Xr 64GB 19
Сейчас вы сохранили количество всех Xiaomi заранее, чтобы не потерять при удалении дубликатов. У вас отлично получается думать наперёд!
Задача №8
Аналогично прошлому заданию обратитесь к третьей строке столбца count
и запишите в ячейку с количеством телефонов HUAWEI P30 lite
обновлённое количество телефонов Huawei
. Ранее сохранили это значение в переменной huawei
.
Выведите таблицу stock на экран и изучите результат.
import pandas as pd
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
xiaomi = stock[stock['item'] == 'Смартфон Xiaomi Redmi 6A 16GB']['count'].sum()
huawei = stock[stock['item'] == 'Смартфон HUAWEI P30 lite']['count'].sum()
stock = stock.drop_duplicates(subset=['item'], keep='first')
stock = stock.reset_index(drop=True)
stock.loc[0, 'count'] = xiaomi
# замените значение в ячейке с количеством смартфонов Huawei
stock.loc[3, 'count'] = huawei
# выведите таблицу stock на экран
print (stock)
id item count
0 100480924 Смартфон Xiaomi Redmi 6A 16GB 44
1 100480938 Смартфон Samsung Galaxy A30 32GB 49
2 100480952 смартфон Samsung Galaxy A30 32gb 11
3 100480959 Смартфон HUAWEI P30 lite 38
4 100480975 Смартфон Apple iPhone Xr 64gb 10
5 100480988 Смартфон Honor 8X 64GB 64
6 100481020 Смартфон Apple iPhone Xr 64GB 19
Вы избавились от дубликатов в смартфонах HUAWEI и Xiaomi. Отлично сработано! Теперь можно двигаться дальше.
Чтобы решить задачу, можно также использовать группировку (groupby) и методы вроде sum() и count(). Но тогда вам понадобился бы навык объединения нескольких таблиц в одну.
Ручной поиск дубликатов с учётом регистра
Сохраните количество телефонов Apple из строки смартфон apple iphone xr 64gb
в переменной apple
. Выведите значение apple
на экран.
import pandas as pd
# служебная строка для печати всех столбцов таблицы на экран
pd.set_option('display.max_columns', None)
stock = pd.read_excel('/datasets/stock.xlsx')
stock['item_lowercase'] = stock['item'].str.lower()
# сохраните количество телефонов Apple
apple = stock[stock['item_lowercase']=='смартфон apple iphone xr 64gb']['count'].sum()
# выведите значение apple на экран
print (apple)
Задание №5
«Перезапишите» stock
и удалите из самого датафрейма строки с дубликатами в столбце item_lowercase
, оставив только первые вхождения: будем считать, что верные идентификаторы товаров для «дубликатов» встречаются первыми в таблице. Решая задание, используйте метод pandas. Когда будете выполнять операцию, не забудьте про параметры subset
и keep
. После не сбрасывайте индексы и выведите на экран всю таблицу.
import pandas as pd
# служебная строка для печати всех столбцов таблицы на экран
pd.set_option('display.max_columns', None)
stock = pd.read_excel('/datasets/stock.xlsx')
stock['item_lowercase'] = stock['item'].str.lower()
apple = stock[stock['item_lowercase'] == 'смартфон apple iphone xr 64gb']['count'].sum()
samsung = stock[stock['item_lowercase'] == 'смартфон samsung galaxy a30 32gb']['count'].sum()
# удалите дубликаты
stock = stock.drop_duplicates(subset=['item_lowercase'], keep='first')
# выведите таблицу stock на экран
print (stock)
Задание №6
В столбце item_lowercase
сбилась нумерация после того, как в нём удалили строки с дубликатами. Допустим, в этом случае в номерах строк нет особого смысла — мы хотим восстановить нумерацию путём сброса пропусков в ней. Восстановите индексы строк методом reset_index()
c параметром drop
, равным True
. Выведите на экран таблицу.
import pandas as pd
# служебная строка для печати всех столбцов таблицы на экран
pd.set_option('display.max_columns', None)
stock = pd.read_excel('/datasets/stock.xlsx', sheet_name='storehouse')
stock['item_lowercase'] = stock['item'].str.lower()
apple = stock[stock['item_lowercase'] == 'смартфон apple iphone xr 64gb']['count'].sum()
samsung = stock[stock['item_lowercase'] == 'смартфон samsung galaxy a30 32gb']['count'].sum()
stock = stock.drop_duplicates(subset=['item_lowercase'], keep='first')
# сбросьте индексы
stock = stock.reset_index(drop=True)
# выведите таблицу stock на экран
print (stock)
Заключение
Проверочные задания. Поиск дубликатов
Чтобы пройти тест нужно правильно ответить на 3 вопроса из 5. Время на прохождение: 10 минут
Задание 1 из 5
Данные записаны в объект Series с именем data. Среди значений встречаются дубликаты, и некоторые из них отличаются только форматированием. Какой код найдёт все повторы и неявные дубликаты?
0 APPLE 1000 ML
1 Apple 750 ml
2 Apple 1000 Ml
3 Apple 1000 ml
4 Apple 1000 ml
dtype: object
Правильный ответ
data.str.lower().duplicated()
Если не предобработать данные, метод duplicated() найдёт только один повтор. Но в данных есть ещё два неявных дубликата: 'APPLE 1000 ML' и 'Apple 1000 Ml'. Нужно привести значения к нижнему регистру с помощью str.lower(). Тогда метод duplicated() найдёт все дубликаты. А метод sum() можно использовать, чтобы их посчитать. Теперь повторов будет три.
Задание 2 из 5
К объекту data применили некоторый код и получили такой результат. Что это был за код?
0 APPLE 1000 ML
1 Apple 750 ml
2 Apple 1000 Ml
3 Apple 1000 ml
4 Apple 1000 ml
dtype: object
0 False
1 False
2 False
3 False
4 True
dtype: bool
Правильный ответ
data.duplicated()
Метод duplicated() вернёт список из True и False. True — если значение уже встречалось. Метод value_counts() тоже возвращает список значений, но в виде пар «значение-частота». А метод sum() в сочетании с другими методами вернёт одно число.
Задание 3 из 5
Как получить такую таблицу из объекта data?
0 APPLE 1000 ML
1 Apple 750 ml
2 Apple 1000 Ml
3 Apple 1000 ml
4 Apple 1000 ml
dtype: object
Apple 1000 ml 2
Apple 750 ml 1
APPLE 1000 ML 1
Apple 1000 Ml 1
dtype: int64
Правильный ответ
data.value_counts()
Такой результат вернёт метод value_counts(). Значения отсортированы по убыванию: самые частотные значения указаны в начале списка.
Задание 4 из 5
Какой код выведет количество явных повторов в объекте data?
0 APPLE 1000 ML
1 Apple 750 ml
2 Apple 1000 Ml
3 Apple 1000 ml
4 Apple 1000 ml
dtype: object
Правильный ответ
data.duplicated().sum()
Метод sum() в сочетании с duplicated() вернёт количество дубликатов. Такой код выведет 1 — столько раз повторяется значение 'Apple 1000 ml'.
Задание 5 из 5
Как перезаписать объект data, удалив все повторы и неявные дубликаты?
0 APPLE 1000 ML
1 Apple 750 ml
2 Apple 1000 Ml
3 Apple 1000 ml
4 Apple 1000 ml
dtype: object
0 apple 1000 ml
1 apple 750 ml
dtype: object
data = data.str.lower().drop_duplicates()
Если применить методы str.lower() и drop_duplicates() к объекту data, код выведет две строки с уникальными значениями. Но сам объект data не изменился — в этом можно убедиться, снова вызвав его. Объект нужно перезаписать, для этого результат присваивают оператором =.
Следующая тема: ПД. Категоризация данных
Вернуться к разделу: "Предобработка данных"
Вернуться в оглавление: Я.Практикум