120 задач Pandas. Часть 2

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

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

import sys
import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt
# 33. Прочитать файл CSV и перевести его в DataFrame

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv')
# 34. Прочитать файл CSV (определенные столбцы и определенное кол-во строк) и перевести его в DataFrame

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=10, usecols=['Name', 'Sex', 'Survived'])
df
# 35. Прочитать файл CSV и перевести каждую 100-ую строку в DataFrame

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', chunksize=100)
df_each = pd.DataFrame()
for chunk in df:
    df_each = df_each.append(chunk.iloc[0,:])
df_each
# 36. Преобразовать индексы объекта Series в столбец DataFrame

test_list = 'abcedf'
test_arr = np.arange(len(test_list))
test_dict = dict(zip(test_list, test_arr))
s = pd.Series(test_dict)

# сбрасываем индексы
df = s.to_frame().reset_index()
# присвоение имёен столбцам
df.columns=['letter', 'number']
df
# 37. Посмотреть информацию объекта DataFrame

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=10)

# Формат каждого столбца
print('\n', 'Формат столбцов:')
print(df.dtypes)

# Размерность DataFrame
print('\n', 'Размерность:')
print(df.shape)

# Общая статистика
print('\n', 'Общая статистика')
print(df.describe())
# 38. Получить данные из DataFrame по условию

s = 'abcdefghijklmnopqrstuvwxyz'

# создаем DataFrame из рандомных цифр
df = pd.DataFrame(np.random.randint(low=1, high=10, size=[3,5]))

# добавляем столбец букв
df = pd.concat([df, pd.DataFrame({'letter': ['a', 'b', 'c']})], axis=1)

# добавляем столбец рандомных букв
df = pd.concat([df, pd.DataFrame({'r_letter': [random.choice(s) for i in range(len(df))]})], axis=1)

print('сформированный DataFrame:')
print(df)
print()

# -------------------------------------------------------------------------------------------------

# получаем номер строки и столбца (индексацию) по условию
row, col = np.where(df.values == 5)
print('индексы строк и столбцов:')
print(row)
print(col)
print()

# получаем данные по индексации (подобно индексации в матрице)
if (row.size != 0) and (col.size != 0):
    print('данные по индексации (строка, столбец):')
    print(df.iat[row[0], col[0]])
    print(df.iloc[row[0], col[0]])
    print()

# получаем данные по индексации и именованому объекту (смешанный тип)
if (row.size != 0) and (col.size != 0):
    print('данные по индексации и наименованию:')
    print(df.at[row[0], 1])
    print(df.at[row[0], 'letter'])
    print()
    
# получаем по условию столбцы и строки DataFrame
# (loc;at - принимают строки(столбцы) с определенными метками из индекса (именованные метки))
# (iloc, iat) - принимают номера строк и столбцов
ans1 = df.loc[df['letter'] == 'a']
print('данные по условию:')
print(ans1)
# 39. Изменить данные столбца DataFrame по условию (по многим условиям)

# загружаем данные (только 10 строк)
df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=10)


# определим функцию для изменения значений в столбце
def change_values(val):
    
    """ тестовая функция измененения значений """
    
    # проверка на числовой тип входящей переменной
    try:
        float(val)
    except Exception as e:
        return val
    
    # условия изменения значений
    if val > 25:
        return 'High'
    elif val < 25:
        return 'Low'
    
col_df = df['Age'].apply(change_values)
col_df
# 40. Переименовать столбец(-ы) в DataFrame(df)

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=10)

# меняем наименование одного столбца
df = df.rename(columns={'Name': 'FullName'})

# изменяем наименования всех столбцов
df.columns = df.columns.map(lambda x: x + '_')

df
# 41. Проверить имеет ли df пропущенные значения

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=10)

# проверка на пропущенные значения
df.isnull().values.any()
# 42. Получить наименование столбцов и сумму пропущенных значений DF

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=20)

# получаем Series суммы пропущенных значений

# вариант 1
missing = df.isnull().sum()

# вариант 2
missing = df.apply(lambda x: x.isnull().sum())

print(missing[missing != 0])
# 43. Заменить пропущенные значения поля "Age" в зависимости от поля "Name"

# данный фрагмент встречается в популярной задаче на kaggle.com о Титанике.
# Решение всей задаче вы можете посмотреть по ссылке:
# "https://github.com/Grossmend/Python-Kaggle/blob/master/machine_learning/Kaggle/Titanic/Solver_Titanic.ipynb"

# у поля "Name" есть Титулы (Mr, Miss, Mrs и т.д.). Нужно проставить пропущенные значения "Age"
# медианой по титулам

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv')

# смотрим на пропущенные значения
print(df.isnull().sum())
print()

# смотрим на первые строки поля "Name"
print(df['Name'].head(10))
print()

# добавляем столбец "Title" (извлекаем из поля "Name" титулы)
df['Title'] = df['Name'].str.extract(' ([A-Za-z]+)\.', expand=False)

# смотрим на частоту встречаемости Титулов
print(df['Title'].value_counts())

# заполняем пропуски "age" в зависимости от "титулов"
df['Age'].fillna(df.groupby('Title')['Age'].transform('median'), inplace=True)
# 44. Задать кол-во строк и столбцов для отображения объектов Pandas

# читаем файл
df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=10)
# устанавливаем отображаемые размеры
# pd.set_option('display.max_columns', 15)
# pd.set_option('display.max_rows', 10)
# смотрим на DataFrame
df
# 45. Заменить (методом Apply) пропущенные значения поля "Min.Price" средним значением и поля Max.Price медианой

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/cars93/Cars93_missing.csv')
d = {'Min.Price': np.nanmean, 'Max.Price': np.nanmedian}
df[['Min.Price', 'Max.Price']] = df[['Min.Price', 'Max.Price']].apply(lambda x, d: x.fillna(d[x.name](x)), args=(d, ))
# 46. Вернуть выбранный столбец DataFrame в качестве объекта DataFrame, а не Series

df = pd.DataFrame(np.arange(20).reshape(4, 5), columns=list('abcde'), index=[3,2,1,0])

# возвращает DataFrame
ans1 = df[['a']]
ans2 = df.loc[[0,1], ['c']]
ans3 = df.iloc[[0,1], [2]]

# # возвращает Series
# df.a
# df['a']
# df.loc[:, 'a']
# df.iloc[:, 1]

print(df)
print()

print(ans1)
print()

print(ans2)
print()

print(ans3)
print()
# 47. Изменить позиции столбцов объекта DataFrame

# 1. Поменять местами столбцы 'a' и 'c'
# 2. Написать функцию, которая меняет столбцы местами
# 3. Сортировать столбцы по наименованию

df = pd.DataFrame(np.arange(20).reshape(4, 5), columns=list('abcde'))

# 1
ans1 = df[list('cbade')]
print(ans1)
print()

# 2
def switch_columns(df, col1=None, col2=None):
    
    if col1:
        if not col1 in df:
            return False
    if col2:
        if not col2 in df:
            return Fasle
    
    colnames = df.columns.tolist()
    i1, i2 = colnames.index(col1), colnames.index(col2)
    colnames[i2], colnames[i1] = colnames[i1], colnames[i2]
    return df[colnames]

ans2 = switch_columns(df, 'd', 'a')
print(ans2)
print()

# 3
ans3 = df[sorted(df.columns)]
print(ans3)
print()
# 48. Создать новый столбец со значениями 0

# создаем DataFrame
df = pd.DataFrame(data=np.arange(20).reshape(4,5), columns=list('abcde'))

# добавляем столбец
df['f'] = 0

df
# 49. Отобрать DataFrame по условию столбца "Age" (где отсутсвуют значения)

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=25)
df[df['Age'].isnull()]
# 50. Отобрать DataFrame по нескольким условиям поля "Age" и "Sex" (пол - мужской, возраст - больше 30)

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=25)
df[(df['Sex'] == 'male') & (df['Age'] > 30)]
# 51. Отобрать DataFrame по полю "Age" (между 30 и 40)

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=25)
df[df['Age'].between(30, 40)]
# 52. Отобрать каждую 20-ую строку и столбцы ['Age', 'Name', 'Survived']

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=100)
df.iloc[::20, :][['Age', 'Name', 'Survived']]
# 53. Заменить в столбце Embarked "S" на число "3"

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/titanic/data.csv', nrows=5)
df['Embarked'].replace('S', 3).to_frame()
# 54. Создать столбец "первичный ключ" объекта DataFrame комбинацией полей

# комбинационные полея: "Manufacturer", "Model", "Type"

df = pd.read_csv('https://raw.githubusercontent.com/Grossmend/CSV/master/cars93/Cars93_missing.csv', usecols=[0,1,2,3,5])

# заменяем пропущенные значения
df[['Manufacturer', 'Model', 'Type']] = df[['Manufacturer', 'Model', 'Type']].fillna('missing')

# присвоение индекса:
df.index = df['Manufacturer'] + '_' + df['Model'] + '_' + df['Type']

# если числовые данные, нужно сначала преобразовать в строчные
# df.index = df['a'].apply(str) + '_' + df['b'].apply(str)

# проверяем все ли индексы уникальны
print('Unique is:', df.index.is_unique)

# смотрим на первые 5 строк
df.head(5)
# 55. Получить номер строки n-ого наибольшего значения в столбце "col"

n = 0
col = 'a'

# создаем DataFrame
df = pd.DataFrame(np.random.randint(low=1, high=100, size=30).reshape(10, 3), columns=list('abc'))
print(df)
print()

# получаем искомый номер строки
ans = df[col].argsort()[::-1].iloc[n]
print(ans)
# 56. Получить номер строки n-ого наименьшего после среднего значения числа в объекте Series

n = 0

s = pd.Series(np.arange(10))

print(s)
print()

print('mean:', round(s.mean(), 2))

ans = np.argwhere(s > s.mean())[n]
print(ans)
# 57. Получить последние n строк объекта DataFrame, где сумма строк больше 100

sum_level = 100
last_row = 2

df = pd.DataFrame(data=np.random.randint(low=10, high=30, size=[50]).reshape(10, 5))

print(df)
print()

rowsums = df.apply(np.sum, axis=1)

last_two_rows = df.iloc[np.where(rowsums > sum_level)[0][-last_row:], :]

print(last_two_rows)
print()
# 58. Убрать верхние и нижние 5% от объекта DataFrame

df = pd.DataFrame(data=np.arange(start=1, stop=21), columns=['data'])

q1 = df['data'].quantile(0.05)
q2 = df['data'].quantile(0.95)

ans = df[(df['data'] > q1) & (df['data'] < q2)]

print(ans)
# 59. После удаления всех отрицательных значений, попытаться сформировать квадратную матрицу из оставшихся положительных значений

df = pd.DataFrame(np.random.randint(-20, 20, 100).reshape(10,10))

print(df)
print()

# оставляем только положительные значения вектора
arr = df[df > 0].values.flatten()
arr_qualified = arr[~np.isnan(arr)]

# определяем размерность квадратной матрицы
n = int(np.floor(arr_qualified.shape[0]**.5))

# формируем матрицу из положительных значений
top_indexes = np.argsort(arr_qualified)[::-1]
output = np.take(arr_qualified, sorted(top_indexes[:n**2])).reshape(n, n)

# переводим в объект DataFrame
df2 = pd.DataFrame(data=output.astype('i'), columns=np.arange(output.shape[1]))

print(df2)
# 60. Поменять местами строки объекта DataFrame

df = pd.DataFrame(np.arange(25).reshape(5, 5))

def swap_rows(df, i1, i2):
    # need check
    a, b = df.iloc[i1, :].copy(), df.iloc[i2, :].copy()
    df.iloc[i1, :], df.iloc[i2, :] = b, a
    return df

ans = swap_rows(df, 1, 3)
print(ans)
# 61. Развернуть строки объекта DataFrame

df = pd.DataFrame(np.arange(25).reshape(5, 5))

# вариант 1
ans1 = df.iloc[::-1, :].reset_index(drop=True)
print(ans1)
print()

# вариант 2
ans2 = df.loc[df.index[::-1], :].reset_index(drop=True)
print(ans2)
print()
# 62. Какой столбец содержит наибольшее кол-во построчно максимальных значений?

# примеч. разберите этот пример...
# (возможно столбцы с одинаковым кол-вом построчно максимальных значений, в данном примере берется "первый")

df = pd.DataFrame(np.random.randint(1, 7, 25).reshape(5, 5))

ans = df.apply(np.argmax, axis=1).value_counts().index[0]

print(df)
print()
print('Столбец:', ans)
# 63. Вычислить максимальное значение абсолютной корреляции столбцов с другими столбцами

df = pd.DataFrame(np.random.randint(1, 100, 80).reshape(8, -1), columns=list('pqrstuvwxy'), index=list('abcdefgh'))
print(df)
print()

# получаем корреляционную матрицу
abs_corrmat = np.abs(df.corr())
# получаем максимальные значения корреляций
max_corr = abs_corrmat.apply(lambda x: sorted(x)[-2])

ans =  np.round(max_corr.tolist(), 2)

print('Максимальное значение корреляции с другими столбцами: ', ans)
Исходники доступы на GitHub

обновлено: Апрель 4, 2019 в 20:24


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

Комментариев нет



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