</center> Автор материала: программист-исследователь Mail.ru Group, старший преподаватель Факультета Компьютерных Наук ВШЭ Юрий Кашницкий. Материал распространяется на условиях лицензии Creative Commons CC BY-NC-SA 4.0. Можно использовать в любых целях (редактировать, поправлять и брать за основу), кроме коммерческих, но с обязательным упоминанием автора материала.
Заполните код в клетках (где написано "Ваш код здесь") и ответьте на вопросы в веб-форме.
In [1]:
import numpy as np
import pandas as pd
%matplotlib inline
from matplotlib import pyplot as plt
pd.set_option("display.precision", 2)
Считаем данные из файла в память в виде объекта Pandas.DataFrame
In [2]:
data = pd.read_csv('../data/titanic_train.csv',
index_col='PassengerId')
Данные представлены в виде таблицы. Посмотрим на первые 5 строк:
In [3]:
data.head(5)
Out[3]:
In [4]:
data.describe()
Out[4]:
Для примера отберем пассажиров, которые сели в Cherbourg (Embarked=C) и заплатили более 200 у.е. за билет (fare > 200).
Убедитесь, что Вы понимаете, как эта конструкция работает.
Если нет – посмотрите, как вычисляется выражение в квадратных в скобках.
In [5]:
data[(data['Embarked'] == 'C') & (data.Fare > 200)].head()
Out[5]:
Можно отсортировать этих людей по убыванию платы за билет.
In [6]:
data[(data['Embarked'] == 'C') &
(data['Fare'] > 200)].sort_values(by='Fare',
ascending=False).head()
Out[6]:
Пример создания признака.
In [7]:
def age_category(age):
'''
< 30 -> 1
>= 30, <55 -> 2
>= 55 -> 3
'''
if age < 30:
return 1
elif age < 55:
return 2
else:
return 3
In [8]:
age_categories = [age_category(age) for age in data.Age]
data['Age_category'] = age_categories
Другой способ – через apply
.
In [9]:
data['Age_category'] = data['Age'].apply(age_category)
1. Сколько мужчин / женщин находилось на борту?
In [10]:
print("На борту было {} мужчин и {} женщин.".format(sum(data['Sex'] == 'male'),
sum(data['Sex'] == 'female')))
Проще:
In [11]:
data['Sex'].value_counts()
Out[11]:
2. Выведите распределение переменной Pclass (социально-экономический статус) и это же распределение, только для мужчин / женщин по отдельности. Сколько было мужчин 2-го класса?
In [12]:
pd.crosstab(data['Pclass'], data['Sex'], margins=True)
Out[12]:
Можно для красоты и картинку нарисовать.
In [13]:
data['Pclass'].hist(label='all')
data[data['Sex'] == 'male']['Pclass'].hist(color="green",
label='male')
data[data['Sex'] == 'female']['Pclass'].hist(color="yellow",
label='female')
plt.title('Distribution by class and gender.')
plt.xlabel('Pclass')
plt.ylabel('Frequency')
plt.legend(loc='upper left');
3. Каковы медиана и стандартное отклонение платежей (Fare
)? Округлите до 2 десятичных знаков.
In [14]:
print("Median fare: ", round(data['Fare'].median(), 2))
print("Fare std: ", round(data['Fare'].std(), 2))
4. Правда ли, что люди моложе 30 лет выживали чаще, чем люди старше 60 лет? Каковы доли выживших в обеих группах?
In [15]:
young_survived = data[data['Age'] < 30]['Survived']
old_survived = data[data['Age'] > 60]['Survived']
print("Доли выживших: \n\t среди молодых {}%, \n\t среди старых {}%.".format(
round(100 * young_survived.mean(), 1),
round(100 * old_survived.mean(), 1)))
5. Правда ли, что женщины выживали чаще мужчин? Каковы доли выживших в обеих группах?
In [16]:
male_survived = data[data['Sex'] == 'male']['Survived']
female_survived = data[data['Sex'] == 'female']['Survived']
print("Доли выживыших: \n\t среди женщин {}%, \n\t среди мужчин {}%".format(
round(100 * female_survived.mean(), 1), round(100 * male_survived.mean(), 1)))
6. Найдите самое популярное имя среди пассажиров Титаника мужского пола?
In [17]:
first_names = data[data['Sex'] == 'male']['Name'].apply(lambda full_name:
full_name.split(',')[1].split()[1])
first_names.value_counts().head()
Out[17]:
7. Сравните графически распределение стоимости билетов и возраста у спасенных и у погибших. Средний возраст погибших выше, верно?
In [18]:
data[data['Survived'] == 1]['Fare'].hist(color="green",
label='Survived')
data[data['Survived'] == 0]['Fare'].hist(color="red",
label='Died')
plt.title('Ticket fare for survived and died')
plt.xlabel('Pounds')
plt.ylabel('Frequency')
plt.legend();
In [19]:
data[data['Survived'] == 1]['Age'].hist(color="green",
label='Survived', alpha=.5)
data[data['Survived'] == 0]['Age'].hist(color="red",
label='Died', alpha=.5)
plt.title('Age for survived and died')
plt.xlabel('Years')
plt.ylabel('Frequency')
plt.legend();
In [20]:
#!conda install seaborn
import seaborn as sns
In [21]:
sns.boxplot(data['Survived'], data['Age']);
На глаз разницы не видно, посчитаем точно. Видно, что в среднем погибшие были старше.
In [22]:
data.groupby('Survived')['Age'].mean()
Out[22]:
8. Как отличается средний возраст мужчин / женщин в зависимости от класса обслуживания? Выберите верные утверждения:
In [23]:
for cl in data['Pclass'].unique():
for sex in data['Sex'].unique():
print("Average age for {0} and class {1}: {2}".format(sex, cl,
round(data[(data['Sex'] == sex)
& (data['Pclass'] == cl)]['Age'].mean(),2)))
Более красивый подход:
In [24]:
for (cl, sex), sub_df in data.groupby(['Pclass', 'Sex']):
print("Average age for {0} and class {1}: {2}".format(sex, cl,
round(sub_df['Age'].mean(), 2)))
И еще круче:
In [25]:
pd.crosstab(data['Pclass'], data['Sex'],
values=data['Age'], aggfunc=np.mean)
Out[25]:
In [26]:
sns.boxplot(data['Pclass'], data['Age']);