Вместе с факультетом Data Science GeekUniversity собрали для вас задачи для практики по самым популярным Python-библиотекам в Data Science: pandas, NumPy и DataTable. Решать задачи можно в любом порядке.
Обратите внимание, что у любой задачи может быть несколько способов решения. Чтобы посмотреть добавленный нами вариант решения, кликните по соответствующей кнопке. Все приведённые варианты написаны на Python 3.
Задачи по pandas
Задача 1
Как найти евклидово расстояние между двумя Series
(точками) a
и b
, не используя встроенную формулу?
Ввод:
a = pd.Series([2, 4, 6, 8]) b = pd.Series([1, 3, 5, 7])
Ожидаемый вывод:
2.0
Вариант решения
# Ввод a = pd.Series([2, 4, 6, 8] b = pd.Series([1, 3, 5, 7]) # Решение sum((a - b)**2)**.5 # Решение (с использованием функции из NumPy) np.linalg.norm(a-b)
Задача 2
Как найти максимально возможное абсолютное значение корреляции каждого столбца с другими столбцами в df
?
Ввод:
df = pd.DataFrame(np.random.randint(1, 100, 16).reshape(4, 4), columns=list('efgh'), index=list('abcd'))
Вариант решения
# Ввод df = pd.DataFrame(np.random.randint(1, 100, 16).reshape(4, 4), columns=list('efgh'), index=list('abcd')) # Решение abs_corr = np.abs(df.corr()) max_corr = abs_corr.apply(lambda x: sorted(x)[-2]) print('Максимальное значение корреляции для каждого столбца: ', np.round(max_corr.tolist(), 2))
Вывод:
Максимальное значение корреляции для каждого столбца: [0.58 0.58 0.76 0.76]
Задача 3
Как нормализовать все столбцы в DataFrame
?
- Нормализуйте все столбцы
df
путём вычитания среднего значения столбца и деления на стандартное отклонение. - Сделайте так, чтобы все значения в
df
находились в диапазоне от 0 до 1.
Ввод:
df = pd.DataFrame(np.random.randint(1, 100, 16).reshape(4, 4))
Вариант решения
# Ввод df = pd.DataFrame(np.random.randint(1, 100, 16).reshape(4, 4)) # Первая часть решения part1 = df.apply(lambda x: ((x - x.mean()) / x.std()).round(2)) print('Первая часть ', part1) # Вторая часть решения part2 = df.apply(lambda x: ((x.max() - x) / (x.max() - x.min())).round(2)) print('Вторая часть ', part2)
Вывод:
Первая часть 0 1 2 3 0 -1.11 -0.87 0.43 0.61 1 -0.57 0.83 -0.50 -0.38 2 0.72 0.91 -1.09 -1.23 3 0.96 -0.87 1.17 0.99 Вторая часть 0 1 2 3 0 1.00 1.00 0.33 0.17 1 0.74 0.05 0.74 0.62 2 0.12 0.00 1.00 1.00 3 0.00 1.00 0.00 0.00
Задача 4
Как объединить два DataFrame
по двум столбцам так, чтобы остались только общие строки?
Объедините df1
и df2
по столбцам fruit-frukt и weight-ves.
Ввод:
df1 = pd.DataFrame({'fruit': ['apple', 'banana', 'orange'] * 3, 'weight': ['low', 'medium', 'high'] * 3, 'price': np.random.randint(0, 100, 9)}) df2 = pd.DataFrame({'frukt': ['apple', 'banana', 'melon'] * 2, 'ves': ['low', 'high'] * 3, 'price': np.random.randint(0, 100, 6)})
Вариант решения
# Ввод df1 = pd.DataFrame({'fruit': ['apple', 'banana', 'orange'] * 3, 'weight': ['low', 'medium', 'high'] * 3, 'price': np.random.randint(0, 100, 9)}) df2 = pd.DataFrame({'frukt': ['apple', 'banana', 'melon'] * 2, 'ves': ['low', 'high'] * 3, 'price': np.random.randint(0, 100, 6)}) # Решение pd.merge(df1, df2, how='inner', left_on=['fruit', 'weight'], right_on=['frukt', 'ves'], suffixes=['_left', '_right'])
Задача 5
Как узнать частоту уникальных значений во всём DataFrame
?
Ввод:
df = pd.DataFrame(np.random.randint(1, 10, 16).reshape(4, 4), columns=list('abcd'))
Вариант решения
# Ввод df = pd.DataFrame(np.random.randint(1, 10, 16).reshape(4, 4), columns=list('abcd')) # Решение pd.value_counts(df.values.ravel())
Вывод:
2 5 8 4 9 2 6 2 5 1 3 1 1 1 dtype: int64
Задача 6
Как создать новый столбец, который содержит номера ближайших по евклидовому расстоянию столбцов?
Ввод:
df = pd.DataFrame(np.random.randint(1, 100, 16).reshape(4, 4), columns=list('efgh'), index=list('abcd')) df # e f g h # a 51 57 11 15 # b 63 5 81 48 # c 7 63 98 88 # d 6 31 29 37
Ожидаемый вывод:
df # e f g h nearest_row dist # a 51 57 11 15 c 122.0 # b 63 5 81 48 a 94.0 # c 7 63 98 88 a 122.0 # d 6 31 29 37 c 92.0
Вариант решения
# Ввод df = pd.DataFrame(np.random.randint(1, 100, 16).reshape(4, 4), columns=list('efgh'), index=list('abcd')) import numpy as np # Инициализация выводов nearest_rows = [] nearest_distance = [] # Проход по строкам for i, row in df.iterrows(): curr = row rest = df.drop(i) dists = {} # инициализируем словарь для евклидовых расстояния для текущей строки # проходим по оставшимся строкам текущей строки for j, contestant in rest.iterrows(): # вычисляем евклидово расстояние и обновляем dists dists.update({j: round(np.linalg.norm(curr.values - contestant.values))}) # приравниваем текущую строку к ближайшей и записываем значение расстояния= nearest_rows.append(max(dists, key=dists.get)) nearest_distance.append(max(dists.values())) df['nearest_row'] = nearest_rows df['dist'] = nearest_distance
Задачи по NumPy
Задача 7
Как поменять местами две строки в двумерном массиве NumPy? Поменяйте местами строки 1 и 3 массива a
.
Ввод:
a = np.arange(9).reshape(3,3)
Вариант решения
# Ввод a = np.arange(9).reshape(3,3) # Решение a[[2, 1, 0], :]
Вывод:
array([[6, 7, 8], [3, 4, 5], [0, 1, 2]])
Задача 8
Как найти количество уникальных значений в массиве NumPy? Найдите уникальные значения и их количество в столбце species
таблицы iris
.
Ввод:
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' iris = np.genfromtxt(url, delimiter=',', dtype='object')
Вариант решения
# Ввод url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' iris = np.genfromtxt(url, delimiter=',', dtype='object') # Решение # Извлекаем столбец species как массив species = np.array([row.tolist()[4] for row in iris]) # Получаем уникальные значения и их количество np.unique(species, return_counts=True)
Вывод:
(array([b'Iris-setosa', b'Iris-versicolor', b'Iris-virginica'], dtype='|S15'), array([50, 50, 50]))
Задача 9
Как найти второе максимальное значение в массиве, который сгруппирован по другому массиву? Найдите значение второго самого длинного petallength
вида setosa
в таблице iris
.
Ввод:
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' iris = np.genfromtxt(url, delimiter=',', dtype='object')
Вариант решения
Решение:
# Ввод url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' iris = np.genfromtxt(url, delimiter=',', dtype='object') # Решение # Извлекаем столбцы вида и длины лепестков setosa_petal_len = iris[iris[:, 4] == b'Iris-setosa', [2]].astype('float') # Получаем второе значение с конца np.unique(np.sort(setosa_petal_len))[-2]
Вывод:
1.7
Задача 10
Как отранжировать элементы массива NumPy?
Ввод:
a = np.random.randint(100, size=10) print(a) # [9 15 64 28 89 93 29 8 73 0]
Ожидаемый вывод:
[2 3 6 4 8 9 5 1 7 0]
Вариант решения
# Ввод a = np.random.randint(100, size=10) # Решение print(a.argsort().argsort())
Задача 11
Как найти результат деления минимального значения на максимальное в каждой строке двумерного массива?
Ввод:
np.random.seed(10) a = np.random.randint(1, 10, [3, 3]) a # array([[5, 1, 2], # [1, 2, 9], # [1, 9, 7]])
Вариант решения
# Ввод np.random.seed(10) a = np.random.randint(1, 10, [3, 3]) # Решение np.apply_along_axis(lambda x: np.min(x) / np.max(x), arr=a, axis=1)
Вывод:
array([0.2, 0.11111111, 0.11111111])
Задача 12
Как найти повторяющиеся значения в массиве NumPy? Найдите повторяющиеся значения (начиная со второго вхождения) в заданном массиве и отметьте их как True
. Первое вхождение отмечайте как False
.
Ввод:
np.random.seed(10) a = np.random.randint(0, 7, 10) print(a) # [1 5 4 0 1 3 4 1 5 0]
Ожидаемый вывод:
[False False False False True False True True True True]
Вариант решения
# Ввод np.random.seed(10) a = np.random.randint(0, 7, 10) # Решение # Создаём массив с True out = np.full(a.shape[0], True) # Находим индексы уникальных элементов pos = np.unique(a, return_index=True)[1] # Помечаем их как False out[pos] = False print(out)
Задача 13
Как удалить из массива NumPy строки, которые содержат nan
?
Ввод:
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' iris = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0, 1, 2, 3]) iris[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan
Вариант решения
Решение:
# Ввод url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' iris = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0, 1, 2, 3]) iris[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan # Решение # Способ 1: nan_in_row = np.array([~np.any(np.isnan(row)) for row in iris]) iris[nan_in_row][:5] # Способ 2: iris[np.sum(np.isnan(iris), axis = 1) == 0][:5]
Вывод:
array([[ 4.9, 3. , 1.4, 0.2], [ 4.7, 3.2, 1.3, 0.2], [ 4.6, 3.1, 1.5, 0.2], [ 5. , 3.6, 1.4, 0.2], [ 5.4, 3.9, 1.7, 0.4]])
Задачи по DataTable
Задача 14
Как сделать left join двух объектов datatable.Frame
? Объедините заданные объекты по ключу А
.
Ввод:
import datatable as dt df1 = dt.Frame(A=[1, 2, 3, 4], B=['a', 'b', 'c', 'd']) df2 = dt.Frame(A=[1, 2, 3, 4, 5], C=['a2', 'b2', 'c2', 'd2', 'e2'])
Вариант решения
# Ввод import datatable as dt df1 = dt.Frame(A=[1, 2, 3, 4], B=['a', 'b', 'c', 'd']) df2 = dt.Frame(A=[1, 2, 3, 4, 5], C=['a2', 'b2', 'c2', 'd2', 'e2']) # Решение df2.key = 'A' output = df1[:, :, dt.join(df2)]
Задача 15
Как преобразовать datatable.Frame
в формат Pandas, NumPy, словаря, списка, кортежа, CSV-файла? Датасет из примера.
Вариант решения
Решение:
import datatable as dt df = dt.fread('https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv') # в DataFrame Pandas pd_df = df.to_pandas() # в массив NumPy arr = df.to_numpy() # в словарь dict_ = df.to_dict() # в список list_ = df[:, 'medv'].to_list() # в кортеж tuples_ = df[:, 'medv'].to_tuples() # в CSV df.to_csv('BostonHousing.csv')
Задача 16
Как узнать типы данных всех столбцов в datatable.Frame
? Датасет из примера.
Ожидаемый вывод:
crim : stype.float64 zn : stype.float64 indus : stype.float64 chas : stype.bool8 nox : stype.float64 rm : stype.float64 age : stype.float64 dis : stype.float64 rad : stype.int32 tax : stype.int32 ptratio : stype.float64 b : stype.float64 lstat : stype.float64 medv : stype.float64
Вариант решения
Решение:
import datatable as dt df = dt.fread('https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv') for i in range(len(df.names)): print(df.names[i], ':', df.stypes[i])