120 задач Pandas. Часть 1. Series

120 задач, благодаря которым вы повысите свою эффективность by Grossmend (Март 5, 2019 в 21:59)

Всем доброго времени суток, представляю вашему вниманию подборку задач Pandas 1-32 объекта "series", благодаря которым значительно увеличится эффективность работы с данной библиотекой. Во многих задачах используются разные варианты решения. Задачи с решениями можно посмотреть в GitHub, ссылка ниже.

# Импортировать модули

import sys
import numpy as np
# 1. Импортировать модуль и проверить версию

import pandas as pd

print(pd.__version__)
print(np.__version__)
print(pd.show_versions(as_json=True))
# 2. Создать объект pandas Series из листа, объекта NumPy, и словаря

src_list = list('abcde')
src_arr = np.arange(5)
src_dict = dict(zip(src_list, src_arr))

s1 = pd.Series(src_list)
s2 = pd.Series(src_arr)
s3 = pd.Series(src_dict)

print(s1)
print(s2)
print(s3)
# 3. Преобразовать объект Seris в DataFrame

# создаем объект Series
s = pd.Series({'a': 'one', 'b': 'two', 'c': 'three'})

# преобразование в DataFrame
s = s.to_frame()

print(s)
# 4. Как объединить несколько объектов Series в Dataframe

s1 = pd.Series(list('abcdefghij'))
s2 = pd.Series(np.arange(10))

# Вариант 1
df1 = pd.concat([s1, s2], axis=1)
print('вариант 1')
print(df1)

# Вариант 2
print('вариант 2')
df2 = pd.DataFrame({'col1': s1, 'col2': s2})
print(df2)
# 5. Присвоить имя индексу объекта Series

s = pd.Series({'a': 1, 'b': 2, 'c': 3})

s.name = 'my_name'

print(s)
# 6. Получить элементы объекта Series A, которых нет в объекте Series B

s1 = pd.Series([1, 2, 3, 4, 5])
s2 = pd.Series([4, 5, 6, 7, 8])

# возвращает вместе с индексами
ans = s1[~s1.isin(s2)]

# возвразает значения
ans2 = np.setdiff1d(s1, s2, assume_unique=False)
print(ans)
# 7. Получить не пересекающиеся элементы в двух объектах Series

s1 = pd.Series([1, 2, 3, 4, 5])
s2 = pd.Series([4, 5, 6, 7, 8])

# возвращает вместе с индексами

# получаем объединенный Series без повтороений
s_union = pd.Series(np.union1d(s1, s2))
# получаем пересекающиеся данные
s_intersect = pd.Series(np.intersect1d(s1, s2))
# отбираем все данные, кроме пересекающихся
ans = s_union[~s_union.isin(s_intersect)]

# возвразает значения
ans2 = np.setxor1d(s1, s2, assume_unique=False)

print(ans)
# 8. Получить от объекта Series показатели описательной статистики

state = np.random.RandomState(42)

s = pd.Series(state.normal(10, 5, 25))
pkz = s.describe()
print(pkz)
# 9. Узнать частоту уникальных элементов объекта Series (гистограмма)

# создаем объект Series функцией с 

data = 'abcdefghik'
len_series = 30
s = pd.Series(np.take(list(data), np.random.randint(len(data), size=len_series)))

# считаем число вхождений
ans = s.value_counts()

print(ans)
# 10. Заменить все элементы объекта Series на "Other", кроме двух наиболее часто встречающихся

state = np.random.RandomState(42)
s = pd.Series(state.randint(low=1, high=5, size=[13]))
print(s.value_counts())
s[~s.isin(s.value_counts().index[:2])] = 'Other'
print(s)
# 11. Создать объект Series в индексах дата каждый день 2018 года, в значениях случайное значение

# 1. Найти сумму всех вторников
# 2. Для каждого месяца найти среднее значение

dti = pd.date_range(start='2018-01-01', end='2018-12-31', freq='B') 
s = pd.Series(np.random.rand(len(dti)), index=dti)

# 1
ans1 = s[s.index.weekday == 2].sum()
print('Сумма всех "вторников"', ans1)
print()

# 2
ans2 = s.resample('M').mean()
print('Средние значения по месяцам:\n', ans2)
print()
# 12. Преобразовать объект Series в DataFrame заданной формы (shape)

s = pd.Series(np.random.randint(low=1, high=10, size=[35]))

# преобразование в reshape
r = (7, 5)

if r[0] * r[1] != len(s):
    sys.exit('не возможно применить reshape')
    
df = pd.DataFrame(s.values.reshape(r))

print(df)
# 13. Найти индексы объекта Series кратные 3

s = pd.Series(np.random.randint(low=1, high=10, size=[7]))

# вариант 1
ans1 = np.argwhere(s % 3==0).flatten()
print(ans1)

# вариант 2
ans2 = s[s % 3 == 0].index
print(ans2)
# 14. Получить данные по индексам объекта Series

s = pd.Series(list('abcdefghijklmnopqrstuvwxyz'))
p = [0, 4, 8, 14, 20, 10]

# вариант 1
ans1 = s[p]
print(ans1)

# вариант 2 (take - также может использовать многоуровневые массивы)
ans2 = s.take(p)
print(ans2)
# 15. Объединить два объекта Series вертикально и горизонтально

s1 = pd.Series(range(5))
s2 = pd.Series(list('abcde'))

ans_vertical = s1.append(s2)
ans_horizontal = pd.concat([s1, s2], axis=1)

print(ans_vertical)
print(ans_horizontal)
# 16. Получить индексы объекта Series A, данные которых содержатся в объетке Series B

s1 = pd.Series([5, 3, 2, 1, 4, 11, 13, 8, 7])
s2 = pd.Series([1, 5, 13, 2])

# вариант 1 (медленный)
ans1 = np.asarray([np.where(i == s1)[0].tolist()[0] for i in s2])
print(ans1)

# вариант 2 (медленный)
ans2 = np.asarray([pd.Index(s1).get_loc(i) for i in s2])
print(ans2)

# вариант 3 (быстрый)
ans3 = np.argwhere(s1.isin(s2)).flatten()
print(ans3)
# 17. Получить объект Series B, котоырй содержит элементы без повторений объекта A

s = pd.Series(np.random.randint(low=1, high=10, size=[10]))
ans = pd.Series(s.unique())
print(ans)
# 18. Преобразовать каждый символ объекта Series в верхний регистр

s = pd.Series(['life', 'is', 'interesting'])

# преобразование данных Series в строку
s = pd.Series(str(i) for i in s)

# вариант 1
ans1 = s.map(lambda x: x.title())
print(ans1)

# вариант 1
ans2 = pd.Series(i.title() for i in s)
print(ans2)
# 19. Рассчитать количество символов в объекте Series

s = pd.Series(['one', 'two', 'three', 'four', 'five'])
# преобразование в строковый тип
s = pd.Series(str(i) for i in s)

# вариант 1
ans1 = np.asarray(s.map(lambda x: len(x)))
print(ans1)

# вариант 2
ans2 = np.asarray([len(i) for i in s])
print(ans2)
# 20. Найти разность между объектом Series и смещением объекта Series на n

n = 1

s = pd.Series([1, 5, 7, 8, 12, 15, 17])

ans = s.diff(periods=n)

print(ans)
# 21 Преобразовать разыне форматы строк объекта Series в дату

s = pd.Series(['2017/01/01', '2015-02-02', '15 Jan 2019'])

# возможно нестабильное решение, необходимо корректно указать строковые значения,
# т.к. могут быть перепутаны месяц и день
ans = pd.to_datetime(s)

print(ans)
# 21.1 Поскольку работа с датой часто встречается в работе, то см. еще один пример

# все данные должны иметь одинаковый формат (часто бывает выгрузка из SQL)
s = pd.Series(['14.02.2019', '22.01.2019', '01.03.2019'])

# преобразование в дату
ans = pd.to_datetime(s, format='%d.%m.%Y')

print(ans)
# 22. Получить год, месяц, день, день недели, номер дня в году от объекта Series (string)

from dateutil.parser import parse

s = pd.Series(['01 Jan 2018', '02-02-2011', '20120303', '2013/04/04', '2018-12-31'])

# парсим в дату и время
s_ts = s.map(lambda x: parse(x, yearfirst=True))

# получаем года
print(s_ts.dt.year)

# получаем месяца
print(s_ts.dt.month)

# получаем дни
print(s_ts.dt.day)

# получаем номер недели
print(s_ts.dt.weekofyear)

# получаем номер дня в году
print(s_ts.dt.dayofyear)
# 23. Преобразовать даты месяца и года к 7-ому дню

from dateutil.parser import parse

s = pd.Series(['Jan 2010', 'Feb 2011', 'Mar 2012'])

ans = s.map(lambda x: parse('04 ' + x))

print(ans)
# 24. Отобрать элементы объекта Series, кторые содержат не менее двух гласных

from collections import Counter

s = pd.Series(['Яблоко', 'Orange', 'Plan', 'Python', 'Апельсин', 'Стол', 'Reliance'])
mask = s.map(lambda x: sum([Counter(x.lower()).get(i, 0) for i in list('aeiouаоиеёэыуюя')]) >= 2)
ans = s[mask]
print(ans)
# 25. Отобрать e-маилы из объекта Series

# модуль для работы с регулярными выражениями
import re

emails = pd.Series(['test text @test.com', 'test@mail.ru', 'test.2ru', 'test@pp'])
pattern = '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}'
mask = emails.map(lambda x: bool(re.match(pattern, x)))
ans = emails[mask]
print(ans)
# 26. Получить среднее значение каждого уникального объекта Series s1 через "маску" другого объекта Series s2

n = 10
s1 = pd.Series(np.random.choice(['dog', 'cat', 'horse', 'bird'], n))
s2 = pd.Series(np.linspace(1,n,n))
ans = s2.groupby(s1).mean()
print(ans)
# 27. Найти евклидово расстоняие между двумя объектами Series

n = 3

s1 = pd.Series(np.random.randint(low=1, high=10, size=[n]))
s2 = pd.Series(np.random.randint(low=1, high=10, size=[n]))

ans = np.linalg.norm(s1-s2)
ans2 = sum((s1-s2)**2)**0.5
print(ans)
# 28. Найти индексы локальных максимумов в объекте Series

s = pd.Series([1, 5, 7, 11, 8, 4, 12, 5, 8, 16, 8])
dd = np.diff(np.sign(np.diff(s)))
ans = np.where(dd == -2)[0] + 1
print(ans)
# 29. Заменить пробелы наименее часто встречающимся символом

str_test = 'bnb ber kekb dare'

s = pd.Series(list(str_test))
freq = s.value_counts()
least_freq = freq.dropna().index[-1]
''.join(s.replace(' ', least_freq))
# 30. Создать объект Series, который содержит в индексах даты выходных дней субботы,
# а в значениях случайные числа от 1 до 10

s = pd.Series(np.random.randint(low=1,high=10,size=[10]), pd.date_range('2018-01-01', periods=10, freq='W-SAT'))
print(s)
# 31. Заполнить пропущенные даты, значением выше (заполненной даты)

s = pd.Series([2, 5, 8, np.nan], index=pd.to_datetime(['2018-01-01', '2018-01-03', '2018-01-06', '2018-01-08']))
# заполнить предыдущими значениями
ans = s.resample('D').ffill()
# заполнить последующими значениями
ans2 = s.resample('D').bfill()
print(ans)
# 32. Вычислить автокорреляцию объекта Series

n = 20

s = pd.Series(np.arange(n))
s = s + np.random.normal(1, 3, n)

autocorr = [s.autocorr(lag=i).round(2) for i in range(n)]

print(autocorr)
Исходники доступы на GitHub

обновлено: Март 6, 2019 в 10:43


Количество комментариев: 4

# 1
Отправитель: Andrey Budenny
Дата: 5 Июнь 2020 в 12:08

Добрый день. оЧЕНЬ ХОТЕЛ БЫ ПОЛУЧИТЬ ДОСТУП К ЗАДАЧАМ. кАК Я МОГУ ЭТО СДЕЛАТЬ ? сПАСИБО

# 2
Отправитель: Алексей
Дата: 23 Июнь 2020 в 10:35

Добрый день! Как получить доступ к остальным задачам?

# 3
Отправитель: Алексей
Дата: 23 Июнь 2020 в 10:37

хотя понятно все) туплю

# 4
Отправитель: Виталий
Дата: 10 Август 2020 в 18:23

№16 самый быстрый s1.index[s1.isin(s2)].tolist()



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