{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Python для сбора данных\n",
"\n",
"*Алла Тамбовцева, НИУ ВШЭ*\n",
"\n",
"### Работа с датафреймами Pandas: часть 2\n",
"\n",
"*Часть 2 включает:* \n",
"\n",
"* Выбор строк по условию.\n",
"* Выбор строк и столбцов по названию и по номеру.\n",
"* Добавление новых столбцов.\n",
"* Удаление пропущенных значений.\n",
"\n",
"Загрузим все тот же файл с данными вымышленного опроса посетителей елочного базара:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"tree = pd.read_csv(\"firtree.csv\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Выбор строк по условию\n",
"\n",
"Часто при работе с датафреймом нас не интересует выбор отдельных строк по названию или номеру, а интересует фильтрация наблюдений – выбор строк датафрейма, которые удовлетворяют определенному условию. Для этого интересующее нас условие необходимо указать в квадратных скобках. Например, выберем только те строки, которые соответствуют людям, готовым отдать более 1500 рублей за елку:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
"
\n",
" \n",
" 5 | \n",
" 6 | \n",
" male | \n",
" сосна Крым | \n",
" 91 | \n",
" 3 | \n",
" 2139 | \n",
" да | \n",
"
\n",
" \n",
" 7 | \n",
" 8 | \n",
" female | \n",
" ель обыкновенная | \n",
" 94 | \n",
" 2 | \n",
" 2707 | \n",
" нет | \n",
"
\n",
" \n",
" 9 | \n",
" 10 | \n",
" male | \n",
" сосна датская | \n",
" 221 | \n",
" 4 | \n",
" 1521 | \n",
" нет | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1192 | \n",
" 1193 | \n",
" male | \n",
" сосна датская | \n",
" 131 | \n",
" 5 | \n",
" 2683 | \n",
" нет | \n",
"
\n",
" \n",
" 1194 | \n",
" 1195 | \n",
" female | \n",
" ель обыкновенная | \n",
" 127 | \n",
" 4 | \n",
" 2932 | \n",
" нет | \n",
"
\n",
" \n",
" 1197 | \n",
" 1198 | \n",
" male | \n",
" сосна Крым | \n",
" 220 | \n",
" 5 | \n",
" 1591 | \n",
" нет | \n",
"
\n",
" \n",
" 1198 | \n",
" 1199 | \n",
" male | \n",
" сосна датская | \n",
" 94 | \n",
" 1 | \n",
" 1966 | \n",
" да | \n",
"
\n",
" \n",
" 1199 | \n",
" 1200 | \n",
" male | \n",
" сосна датская | \n",
" 105 | \n",
" 5 | \n",
" 2204 | \n",
" нет | \n",
"
\n",
" \n",
"
\n",
"
652 rows × 7 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish\n",
"1 2 male пихта Нобилис 174 3 2378 нет\n",
"3 4 female сосна Крым 191 1 2934 да\n",
"5 6 male сосна Крым 91 3 2139 да\n",
"7 8 female ель обыкновенная 94 2 2707 нет\n",
"9 10 male сосна датская 221 4 1521 нет\n",
"... ... ... ... ... ... ... ...\n",
"1192 1193 male сосна датская 131 5 2683 нет\n",
"1194 1195 female ель обыкновенная 127 4 2932 нет\n",
"1197 1198 male сосна Крым 220 5 1591 нет\n",
"1198 1199 male сосна датская 94 1 1966 да\n",
"1199 1200 male сосна датская 105 5 2204 нет\n",
"\n",
"[652 rows x 7 columns]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[tree[\"expenses\"] > 1500]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Почему нельзя было написать проще, то есть `tree[\"expenses\"] > 1500`? Давайте напишем, и посмотрим, что получится:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 False\n",
"1 True\n",
"2 False\n",
"3 True\n",
"4 False\n",
" ... \n",
"1195 False\n",
"1196 False\n",
"1197 True\n",
"1198 True\n",
"1199 True\n",
"Name: expenses, Length: 1200, dtype: bool"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[\"expenses\"] > 1500"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Что мы увидели? Просто результат проверки условия, набор из `True` и `False`. Когда мы подставляем это выражение в квадратные скобки, Python выбирает из `tree` те строки, где выражение принимает значение `True`.\n",
"\n",
"Все операторы для проверки и объединения условий работают как обычно. Например, два условия одновременно: строки, соответствующие елкам, которые оценили дороже 1500 рублей и которые респонденты хотели бы приобрести себе:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
"
\n",
" \n",
" 5 | \n",
" 6 | \n",
" male | \n",
" сосна Крым | \n",
" 91 | \n",
" 3 | \n",
" 2139 | \n",
" да | \n",
"
\n",
" \n",
" 17 | \n",
" 18 | \n",
" male | \n",
" сосна датская | \n",
" 151 | \n",
" 5 | \n",
" 2715 | \n",
" да | \n",
"
\n",
" \n",
" 18 | \n",
" 19 | \n",
" male | \n",
" сосна Крым | \n",
" 227 | \n",
" 3 | \n",
" 2771 | \n",
" да | \n",
"
\n",
" \n",
" 22 | \n",
" 23 | \n",
" female | \n",
" пихта Нобилис | \n",
" 128 | \n",
" 4 | \n",
" 2424 | \n",
" да | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1186 | \n",
" 1187 | \n",
" female | \n",
" ель обыкновенная | \n",
" 246 | \n",
" 2 | \n",
" 2861 | \n",
" да | \n",
"
\n",
" \n",
" 1188 | \n",
" 1189 | \n",
" female | \n",
" пихта Нобилис | \n",
" 103 | \n",
" 5 | \n",
" 2647 | \n",
" да | \n",
"
\n",
" \n",
" 1189 | \n",
" 1190 | \n",
" female | \n",
" ель обыкновенная | \n",
" 226 | \n",
" 5 | \n",
" 2990 | \n",
" да | \n",
"
\n",
" \n",
" 1191 | \n",
" 1192 | \n",
" male | \n",
" пихта Нобилис | \n",
" 158 | \n",
" 4 | \n",
" 2715 | \n",
" да | \n",
"
\n",
" \n",
" 1198 | \n",
" 1199 | \n",
" male | \n",
" сосна датская | \n",
" 94 | \n",
" 1 | \n",
" 1966 | \n",
" да | \n",
"
\n",
" \n",
"
\n",
"
354 rows × 7 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish\n",
"3 4 female сосна Крым 191 1 2934 да\n",
"5 6 male сосна Крым 91 3 2139 да\n",
"17 18 male сосна датская 151 5 2715 да\n",
"18 19 male сосна Крым 227 3 2771 да\n",
"22 23 female пихта Нобилис 128 4 2424 да\n",
"... ... ... ... ... ... ... ...\n",
"1186 1187 female ель обыкновенная 246 2 2861 да\n",
"1188 1189 female пихта Нобилис 103 5 2647 да\n",
"1189 1190 female ель обыкновенная 226 5 2990 да\n",
"1191 1192 male пихта Нобилис 158 4 2715 да\n",
"1198 1199 male сосна датская 94 1 1966 да\n",
"\n",
"[354 rows x 7 columns]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[(tree[\"expenses\"] > 1500) & (tree[\"wish\"] == \"да\")]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Все сосны, либо сосны Крым, либо датские сосны:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
"
\n",
" \n",
" 5 | \n",
" 6 | \n",
" male | \n",
" сосна Крым | \n",
" 91 | \n",
" 3 | \n",
" 2139 | \n",
" да | \n",
"
\n",
" \n",
" 9 | \n",
" 10 | \n",
" male | \n",
" сосна датская | \n",
" 221 | \n",
" 4 | \n",
" 1521 | \n",
" нет | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1192 | \n",
" 1193 | \n",
" male | \n",
" сосна датская | \n",
" 131 | \n",
" 5 | \n",
" 2683 | \n",
" нет | \n",
"
\n",
" \n",
" 1193 | \n",
" 1194 | \n",
" male | \n",
" сосна Крым | \n",
" 138 | \n",
" 4 | \n",
" 304 | \n",
" да | \n",
"
\n",
" \n",
" 1197 | \n",
" 1198 | \n",
" male | \n",
" сосна Крым | \n",
" 220 | \n",
" 5 | \n",
" 1591 | \n",
" нет | \n",
"
\n",
" \n",
" 1198 | \n",
" 1199 | \n",
" male | \n",
" сосна датская | \n",
" 94 | \n",
" 1 | \n",
" 1966 | \n",
" да | \n",
"
\n",
" \n",
" 1199 | \n",
" 1200 | \n",
" male | \n",
" сосна датская | \n",
" 105 | \n",
" 5 | \n",
" 2204 | \n",
" нет | \n",
"
\n",
" \n",
"
\n",
"
616 rows × 7 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish\n",
"2 3 female сосна Крым 248 4 655 да\n",
"3 4 female сосна Крым 191 1 2934 да\n",
"4 5 female сосна Крым 147 3 1198 нет\n",
"5 6 male сосна Крым 91 3 2139 да\n",
"9 10 male сосна датская 221 4 1521 нет\n",
"... ... ... ... ... ... ... ...\n",
"1192 1193 male сосна датская 131 5 2683 нет\n",
"1193 1194 male сосна Крым 138 4 304 да\n",
"1197 1198 male сосна Крым 220 5 1591 нет\n",
"1198 1199 male сосна датская 94 1 1966 да\n",
"1199 1200 male сосна датская 105 5 2204 нет\n",
"\n",
"[616 rows x 7 columns]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[(tree[\"ftype\"] == \"сосна Крым\" ) | (tree[\"ftype\"] == \"сосна датская\")]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Если бы типов сосен было много, было бы неудобно прописывать через `|` условия для каждого типа. Тогда логично было бы воспользоваться методом, который позволяет выбрать все строки, где в ячейке с текстом встречается слово «сосна». Такой метод есть – это метод на строках `.contains()`, который возвращает `True` если некоторая подстрока (набор символов) входит в строку, и `False` – в противном случае."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
"
\n",
" \n",
" 5 | \n",
" 6 | \n",
" male | \n",
" сосна Крым | \n",
" 91 | \n",
" 3 | \n",
" 2139 | \n",
" да | \n",
"
\n",
" \n",
" 9 | \n",
" 10 | \n",
" male | \n",
" сосна датская | \n",
" 221 | \n",
" 4 | \n",
" 1521 | \n",
" нет | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1192 | \n",
" 1193 | \n",
" male | \n",
" сосна датская | \n",
" 131 | \n",
" 5 | \n",
" 2683 | \n",
" нет | \n",
"
\n",
" \n",
" 1193 | \n",
" 1194 | \n",
" male | \n",
" сосна Крым | \n",
" 138 | \n",
" 4 | \n",
" 304 | \n",
" да | \n",
"
\n",
" \n",
" 1197 | \n",
" 1198 | \n",
" male | \n",
" сосна Крым | \n",
" 220 | \n",
" 5 | \n",
" 1591 | \n",
" нет | \n",
"
\n",
" \n",
" 1198 | \n",
" 1199 | \n",
" male | \n",
" сосна датская | \n",
" 94 | \n",
" 1 | \n",
" 1966 | \n",
" да | \n",
"
\n",
" \n",
" 1199 | \n",
" 1200 | \n",
" male | \n",
" сосна датская | \n",
" 105 | \n",
" 5 | \n",
" 2204 | \n",
" нет | \n",
"
\n",
" \n",
"
\n",
"
616 rows × 7 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish\n",
"2 3 female сосна Крым 248 4 655 да\n",
"3 4 female сосна Крым 191 1 2934 да\n",
"4 5 female сосна Крым 147 3 1198 нет\n",
"5 6 male сосна Крым 91 3 2139 да\n",
"9 10 male сосна датская 221 4 1521 нет\n",
"... ... ... ... ... ... ... ...\n",
"1192 1193 male сосна датская 131 5 2683 нет\n",
"1193 1194 male сосна Крым 138 4 304 да\n",
"1197 1198 male сосна Крым 220 5 1591 нет\n",
"1198 1199 male сосна датская 94 1 1966 да\n",
"1199 1200 male сосна датская 105 5 2204 нет\n",
"\n",
"[616 rows x 7 columns]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[tree[\"ftype\"].str.contains(\"сосна\")]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"А если наоборот, нам нужно отрицание – все строки, которые относятся к чему угодно, только не к соснам? Можно проверить равенство `False`:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
"
\n",
" \n",
" 6 | \n",
" 7 | \n",
" male | \n",
" ель обыкновенная | \n",
" 151 | \n",
" 5 | \n",
" 702 | \n",
" да | \n",
"
\n",
" \n",
" 7 | \n",
" 8 | \n",
" female | \n",
" ель обыкновенная | \n",
" 94 | \n",
" 2 | \n",
" 2707 | \n",
" нет | \n",
"
\n",
" \n",
" 8 | \n",
" 9 | \n",
" female | \n",
" ель обыкновенная | \n",
" 138 | \n",
" 5 | \n",
" 713 | \n",
" нет | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1189 | \n",
" 1190 | \n",
" female | \n",
" ель обыкновенная | \n",
" 226 | \n",
" 5 | \n",
" 2990 | \n",
" да | \n",
"
\n",
" \n",
" 1191 | \n",
" 1192 | \n",
" male | \n",
" пихта Нобилис | \n",
" 158 | \n",
" 4 | \n",
" 2715 | \n",
" да | \n",
"
\n",
" \n",
" 1194 | \n",
" 1195 | \n",
" female | \n",
" ель обыкновенная | \n",
" 127 | \n",
" 4 | \n",
" 2932 | \n",
" нет | \n",
"
\n",
" \n",
" 1195 | \n",
" 1196 | \n",
" male | \n",
" ель обыкновенная | \n",
" 137 | \n",
" 2 | \n",
" 1298 | \n",
" нет | \n",
"
\n",
" \n",
" 1196 | \n",
" 1197 | \n",
" female | \n",
" пихта Нобилис | \n",
" 141 | \n",
" 3 | \n",
" 906 | \n",
" да | \n",
"
\n",
" \n",
"
\n",
"
584 rows × 7 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish\n",
"0 1 female пихта Нобилис 190 3 1051 да\n",
"1 2 male пихта Нобилис 174 3 2378 нет\n",
"6 7 male ель обыкновенная 151 5 702 да\n",
"7 8 female ель обыкновенная 94 2 2707 нет\n",
"8 9 female ель обыкновенная 138 5 713 нет\n",
"... ... ... ... ... ... ... ...\n",
"1189 1190 female ель обыкновенная 226 5 2990 да\n",
"1191 1192 male пихта Нобилис 158 4 2715 да\n",
"1194 1195 female ель обыкновенная 127 4 2932 нет\n",
"1195 1196 male ель обыкновенная 137 2 1298 нет\n",
"1196 1197 female пихта Нобилис 141 3 906 да\n",
"\n",
"[584 rows x 7 columns]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[tree[\"ftype\"].str.contains(\"сосна\") == False]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"А можно воспользоваться оператором `~` для отрицания и поставить его перед всем условием в скобках:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
"
\n",
" \n",
" 6 | \n",
" 7 | \n",
" male | \n",
" ель обыкновенная | \n",
" 151 | \n",
" 5 | \n",
" 702 | \n",
" да | \n",
"
\n",
" \n",
" 7 | \n",
" 8 | \n",
" female | \n",
" ель обыкновенная | \n",
" 94 | \n",
" 2 | \n",
" 2707 | \n",
" нет | \n",
"
\n",
" \n",
" 8 | \n",
" 9 | \n",
" female | \n",
" ель обыкновенная | \n",
" 138 | \n",
" 5 | \n",
" 713 | \n",
" нет | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1189 | \n",
" 1190 | \n",
" female | \n",
" ель обыкновенная | \n",
" 226 | \n",
" 5 | \n",
" 2990 | \n",
" да | \n",
"
\n",
" \n",
" 1191 | \n",
" 1192 | \n",
" male | \n",
" пихта Нобилис | \n",
" 158 | \n",
" 4 | \n",
" 2715 | \n",
" да | \n",
"
\n",
" \n",
" 1194 | \n",
" 1195 | \n",
" female | \n",
" ель обыкновенная | \n",
" 127 | \n",
" 4 | \n",
" 2932 | \n",
" нет | \n",
"
\n",
" \n",
" 1195 | \n",
" 1196 | \n",
" male | \n",
" ель обыкновенная | \n",
" 137 | \n",
" 2 | \n",
" 1298 | \n",
" нет | \n",
"
\n",
" \n",
" 1196 | \n",
" 1197 | \n",
" female | \n",
" пихта Нобилис | \n",
" 141 | \n",
" 3 | \n",
" 906 | \n",
" да | \n",
"
\n",
" \n",
"
\n",
"
584 rows × 7 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish\n",
"0 1 female пихта Нобилис 190 3 1051 да\n",
"1 2 male пихта Нобилис 174 3 2378 нет\n",
"6 7 male ель обыкновенная 151 5 702 да\n",
"7 8 female ель обыкновенная 94 2 2707 нет\n",
"8 9 female ель обыкновенная 138 5 713 нет\n",
"... ... ... ... ... ... ... ...\n",
"1189 1190 female ель обыкновенная 226 5 2990 да\n",
"1191 1192 male пихта Нобилис 158 4 2715 да\n",
"1194 1195 female ель обыкновенная 127 4 2932 нет\n",
"1195 1196 male ель обыкновенная 137 2 1298 нет\n",
"1196 1197 female пихта Нобилис 141 3 906 да\n",
"\n",
"[584 rows x 7 columns]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[~tree[\"ftype\"].str.contains(\"сосна\")]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В `str` хранится множество удобных методов, которые во многом повторяют методы на строках, с которыми мы уже знакомы. Например, метод `.split()`. Разобьем все строки в ячейках столбца `ftype` по пробелу:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 [пихта, Нобилис]\n",
"1 [пихта, Нобилис]\n",
"2 [сосна, Крым]\n",
"3 [сосна, Крым]\n",
"4 [сосна, Крым]\n",
" ... \n",
"1195 [ель, обыкновенная]\n",
"1196 [пихта, Нобилис]\n",
"1197 [сосна, Крым]\n",
"1198 [сосна, датская]\n",
"1199 [сосна, датская]\n",
"Name: ftype, Length: 1200, dtype: object"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[\"ftype\"].str.split()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Чтобы создать новые столбцы вместо списков внутри одного, можно добавить аргумент `expand=True`. "
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" 0 | \n",
" 1 | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" пихта | \n",
" Нобилис | \n",
"
\n",
" \n",
" 1 | \n",
" пихта | \n",
" Нобилис | \n",
"
\n",
" \n",
" 2 | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" 3 | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" 4 | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1195 | \n",
" ель | \n",
" обыкновенная | \n",
"
\n",
" \n",
" 1196 | \n",
" пихта | \n",
" Нобилис | \n",
"
\n",
" \n",
" 1197 | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" 1198 | \n",
" сосна | \n",
" датская | \n",
"
\n",
" \n",
" 1199 | \n",
" сосна | \n",
" датская | \n",
"
\n",
" \n",
"
\n",
"
1200 rows × 2 columns
\n",
"
"
],
"text/plain": [
" 0 1\n",
"0 пихта Нобилис\n",
"1 пихта Нобилис\n",
"2 сосна Крым\n",
"3 сосна Крым\n",
"4 сосна Крым\n",
"... ... ...\n",
"1195 ель обыкновенная\n",
"1196 пихта Нобилис\n",
"1197 сосна Крым\n",
"1198 сосна датская\n",
"1199 сосна датская\n",
"\n",
"[1200 rows x 2 columns]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[\"ftype\"].str.split(expand= True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Код выше вернул нам новый датафрейм. Мы можем сохранить его в переменную `tree2`, а потом объединить `tree` и `tree2` с помощью функции `concat()`:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
" 0 | \n",
" 1 | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
" пихта | \n",
" Нобилис | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
" пихта | \n",
" Нобилис | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1195 | \n",
" 1196 | \n",
" male | \n",
" ель обыкновенная | \n",
" 137 | \n",
" 2 | \n",
" 1298 | \n",
" нет | \n",
" ель | \n",
" обыкновенная | \n",
"
\n",
" \n",
" 1196 | \n",
" 1197 | \n",
" female | \n",
" пихта Нобилис | \n",
" 141 | \n",
" 3 | \n",
" 906 | \n",
" да | \n",
" пихта | \n",
" Нобилис | \n",
"
\n",
" \n",
" 1197 | \n",
" 1198 | \n",
" male | \n",
" сосна Крым | \n",
" 220 | \n",
" 5 | \n",
" 1591 | \n",
" нет | \n",
" сосна | \n",
" Крым | \n",
"
\n",
" \n",
" 1198 | \n",
" 1199 | \n",
" male | \n",
" сосна датская | \n",
" 94 | \n",
" 1 | \n",
" 1966 | \n",
" да | \n",
" сосна | \n",
" датская | \n",
"
\n",
" \n",
" 1199 | \n",
" 1200 | \n",
" male | \n",
" сосна датская | \n",
" 105 | \n",
" 5 | \n",
" 2204 | \n",
" нет | \n",
" сосна | \n",
" датская | \n",
"
\n",
" \n",
"
\n",
"
1200 rows × 9 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish \\\n",
"0 1 female пихта Нобилис 190 3 1051 да \n",
"1 2 male пихта Нобилис 174 3 2378 нет \n",
"2 3 female сосна Крым 248 4 655 да \n",
"3 4 female сосна Крым 191 1 2934 да \n",
"4 5 female сосна Крым 147 3 1198 нет \n",
"... ... ... ... ... ... ... ... \n",
"1195 1196 male ель обыкновенная 137 2 1298 нет \n",
"1196 1197 female пихта Нобилис 141 3 906 да \n",
"1197 1198 male сосна Крым 220 5 1591 нет \n",
"1198 1199 male сосна датская 94 1 1966 да \n",
"1199 1200 male сосна датская 105 5 2204 нет \n",
"\n",
" 0 1 \n",
"0 пихта Нобилис \n",
"1 пихта Нобилис \n",
"2 сосна Крым \n",
"3 сосна Крым \n",
"4 сосна Крым \n",
"... ... ... \n",
"1195 ель обыкновенная \n",
"1196 пихта Нобилис \n",
"1197 сосна Крым \n",
"1198 сосна датская \n",
"1199 сосна датская \n",
"\n",
"[1200 rows x 9 columns]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree2 = tree[\"ftype\"].str.split(expand= True)\n",
"pd.concat([tree, tree2], axis = 1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Аргумент `axis=1` нужен для того, чтобы датафреймы склеивались по столбцам, то есть, чтобы датафрейм `tree2` разместился справа от `tree`. По умолчанию `axis=0`, поэтому, если аргумент `axis` не изменить, строки из `tree2` будут приклеены к строкам из `tree` снизу."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Выбор строк и столбцов по названию и по номеру"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Отдельный столбец по названию мы уже выбрали:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 да\n",
"1 нет\n",
"2 да\n",
"3 да\n",
"4 нет\n",
" ... \n",
"1195 нет\n",
"1196 да\n",
"1197 нет\n",
"1198 да\n",
"1199 нет\n",
"Name: wish, Length: 1200, dtype: object"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[\"wish\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Если нам нужно сразу несколько столбцов (маленький датафрейм на основе старого), то названия столбцов необходимо оформить в виде списка и указать его в квадратных скобках:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" ftype | \n",
" score | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" пихта Нобилис | \n",
" 3 | \n",
"
\n",
" \n",
" 1 | \n",
" пихта Нобилис | \n",
" 3 | \n",
"
\n",
" \n",
" 2 | \n",
" сосна Крым | \n",
" 4 | \n",
"
\n",
" \n",
" 3 | \n",
" сосна Крым | \n",
" 1 | \n",
"
\n",
" \n",
" 4 | \n",
" сосна Крым | \n",
" 3 | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1195 | \n",
" ель обыкновенная | \n",
" 2 | \n",
"
\n",
" \n",
" 1196 | \n",
" пихта Нобилис | \n",
" 3 | \n",
"
\n",
" \n",
" 1197 | \n",
" сосна Крым | \n",
" 5 | \n",
"
\n",
" \n",
" 1198 | \n",
" сосна датская | \n",
" 1 | \n",
"
\n",
" \n",
" 1199 | \n",
" сосна датская | \n",
" 5 | \n",
"
\n",
" \n",
"
\n",
"
1200 rows × 2 columns
\n",
"
"
],
"text/plain": [
" ftype score\n",
"0 пихта Нобилис 3\n",
"1 пихта Нобилис 3\n",
"2 сосна Крым 4\n",
"3 сосна Крым 1\n",
"4 сосна Крым 3\n",
"... ... ...\n",
"1195 ель обыкновенная 2\n",
"1196 пихта Нобилис 3\n",
"1197 сосна Крым 5\n",
"1198 сосна датская 1\n",
"1199 сосна датская 5\n",
"\n",
"[1200 rows x 2 columns]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[[\"ftype\", \"score\"]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Если нам нужно несколько столбцов подряд, начиная с одного названия и заканчивая другим, можно воспользоваться методом `.loc`:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" ftype | \n",
" height | \n",
" score | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
"
\n",
" \n",
" 1 | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
"
\n",
" \n",
" 2 | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
"
\n",
" \n",
" 3 | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
"
\n",
" \n",
" 4 | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1195 | \n",
" ель обыкновенная | \n",
" 137 | \n",
" 2 | \n",
"
\n",
" \n",
" 1196 | \n",
" пихта Нобилис | \n",
" 141 | \n",
" 3 | \n",
"
\n",
" \n",
" 1197 | \n",
" сосна Крым | \n",
" 220 | \n",
" 5 | \n",
"
\n",
" \n",
" 1198 | \n",
" сосна датская | \n",
" 94 | \n",
" 1 | \n",
"
\n",
" \n",
" 1199 | \n",
" сосна датская | \n",
" 105 | \n",
" 5 | \n",
"
\n",
" \n",
"
\n",
"
1200 rows × 3 columns
\n",
"
"
],
"text/plain": [
" ftype height score\n",
"0 пихта Нобилис 190 3\n",
"1 пихта Нобилис 174 3\n",
"2 сосна Крым 248 4\n",
"3 сосна Крым 191 1\n",
"4 сосна Крым 147 3\n",
"... ... ... ...\n",
"1195 ель обыкновенная 137 2\n",
"1196 пихта Нобилис 141 3\n",
"1197 сосна Крым 220 5\n",
"1198 сосна датская 94 1\n",
"1199 сосна датская 105 5\n",
"\n",
"[1200 rows x 3 columns]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.loc[:, \"ftype\":\"score\"] "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Метод `.loc` используется для выбора определенных строк и столбцов, поэтому в квадратных скобках образуется запись через запятую: на первом месте условия для строк, на втором – для столбцов. Здесь нас интересуют все строки (полный срез через `:`) и конкретные столбцы, с `ftype` по `score` включительно. \n",
"\n",
"Если бы мы хотели выбрать строки с 0 по 12 и столбцы с `ftype` по `score`, тоже бы пригодился метод `.loc`:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" ftype | \n",
" height | \n",
" score | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
"
\n",
" \n",
" 1 | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
"
\n",
" \n",
" 2 | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
"
\n",
" \n",
" 3 | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
"
\n",
" \n",
" 4 | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
"
\n",
" \n",
" 5 | \n",
" сосна Крым | \n",
" 91 | \n",
" 3 | \n",
"
\n",
" \n",
" 6 | \n",
" ель обыкновенная | \n",
" 151 | \n",
" 5 | \n",
"
\n",
" \n",
" 7 | \n",
" ель обыкновенная | \n",
" 94 | \n",
" 2 | \n",
"
\n",
" \n",
" 8 | \n",
" ель обыкновенная | \n",
" 138 | \n",
" 5 | \n",
"
\n",
" \n",
" 9 | \n",
" сосна датская | \n",
" 221 | \n",
" 4 | \n",
"
\n",
" \n",
" 10 | \n",
" сосна Крым | \n",
" 162 | \n",
" 1 | \n",
"
\n",
" \n",
" 11 | \n",
" ель обыкновенная | \n",
" 149 | \n",
" 5 | \n",
"
\n",
" \n",
" 12 | \n",
" ель обыкновенная | \n",
" 160 | \n",
" 2 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" ftype height score\n",
"0 пихта Нобилис 190 3\n",
"1 пихта Нобилис 174 3\n",
"2 сосна Крым 248 4\n",
"3 сосна Крым 191 1\n",
"4 сосна Крым 147 3\n",
"5 сосна Крым 91 3\n",
"6 ель обыкновенная 151 5\n",
"7 ель обыкновенная 94 2\n",
"8 ель обыкновенная 138 5\n",
"9 сосна датская 221 4\n",
"10 сосна Крым 162 1\n",
"11 ель обыкновенная 149 5\n",
"12 ель обыкновенная 160 2"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.loc[0:12, \"ftype\":\"score\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Внимание:** хотя в `.loc` мы задействуем обычные питоновские срезы, внутри этого метода срезы включают как левый, так и *правый* конец среза. Так, в примере выше были выбраны строки по 12-ую включительно и столбец `score` так же был включен."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Иногда может возникнуть необходимость выбрать столбец по его порядковому номеру. Например, когда названий столбцов нет как таковых или когда названия слишком длинные, а переименовывать их нежелательно. Сделать это можно с помощью метода `.iloc` (`i` – от *index*). Выберем строки с 0 по 11 и столбцы со второго по третий:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" ftype | \n",
" height | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" пихта Нобилис | \n",
" 190 | \n",
"
\n",
" \n",
" 1 | \n",
" пихта Нобилис | \n",
" 174 | \n",
"
\n",
" \n",
" 2 | \n",
" сосна Крым | \n",
" 248 | \n",
"
\n",
" \n",
" 3 | \n",
" сосна Крым | \n",
" 191 | \n",
"
\n",
" \n",
" 4 | \n",
" сосна Крым | \n",
" 147 | \n",
"
\n",
" \n",
" 5 | \n",
" сосна Крым | \n",
" 91 | \n",
"
\n",
" \n",
" 6 | \n",
" ель обыкновенная | \n",
" 151 | \n",
"
\n",
" \n",
" 7 | \n",
" ель обыкновенная | \n",
" 94 | \n",
"
\n",
" \n",
" 8 | \n",
" ель обыкновенная | \n",
" 138 | \n",
"
\n",
" \n",
" 9 | \n",
" сосна датская | \n",
" 221 | \n",
"
\n",
" \n",
" 10 | \n",
" сосна Крым | \n",
" 162 | \n",
"
\n",
" \n",
" 11 | \n",
" ель обыкновенная | \n",
" 149 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" ftype height\n",
"0 пихта Нобилис 190\n",
"1 пихта Нобилис 174\n",
"2 сосна Крым 248\n",
"3 сосна Крым 191\n",
"4 сосна Крым 147\n",
"5 сосна Крым 91\n",
"6 ель обыкновенная 151\n",
"7 ель обыкновенная 94\n",
"8 ель обыкновенная 138\n",
"9 сосна датская 221\n",
"10 сосна Крым 162\n",
"11 ель обыкновенная 149"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.iloc[0:12, 2:4]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Внимание:** в методе `.iloc`, поскольку работа идет с обычными числовыми индексами (как в списках и кортежах), правый конец среза исключается. Поэтому в примере выше 12-я строка и 4-ый столбец показаны не были."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Если в `.iloc` вписать только одно число, по умолчанию будет выдана строка с таким номером:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Unnamed: 0 3\n",
"gender female\n",
"ftype сосна Крым\n",
"height 248\n",
"score 4\n",
"expenses 655\n",
"wish да\n",
"Name: 2, dtype: object"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.iloc[2]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Это будет объект типа *pandas Series*:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"pandas.core.series.Series"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(tree.iloc[2]) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Переименование столбцов"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Посмотрим на список названий всех столбцов (точнее, это будет объект специального типа `Index`, который внутри очень похож на массив):"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['Unnamed: 0', 'gender', 'ftype', 'height', 'score', 'expenses', 'wish'], dtype='object')"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.columns"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Аналогичным образом посмотрим на названия строк:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"RangeIndex(start=0, stop=1200, step=1)"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.index"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Строки не имеют специально заданных текстовых названий, поэтому они автоматически названы по промежутку из целых чисел `RangeIndex` от 0 до 1200.\n",
"\n",
"Теперь попробуем переименовать столбец `Unnamed: 0` и дать ему более симпатичное название. Так как это по сути номер респондента, назовем его `id`. Воспользуемся методом `.rename()`:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 1195 | \n",
" 1196 | \n",
" male | \n",
" ель обыкновенная | \n",
" 137 | \n",
" 2 | \n",
" 1298 | \n",
" нет | \n",
"
\n",
" \n",
" 1196 | \n",
" 1197 | \n",
" female | \n",
" пихта Нобилис | \n",
" 141 | \n",
" 3 | \n",
" 906 | \n",
" да | \n",
"
\n",
" \n",
" 1197 | \n",
" 1198 | \n",
" male | \n",
" сосна Крым | \n",
" 220 | \n",
" 5 | \n",
" 1591 | \n",
" нет | \n",
"
\n",
" \n",
" 1198 | \n",
" 1199 | \n",
" male | \n",
" сосна датская | \n",
" 94 | \n",
" 1 | \n",
" 1966 | \n",
" да | \n",
"
\n",
" \n",
" 1199 | \n",
" 1200 | \n",
" male | \n",
" сосна датская | \n",
" 105 | \n",
" 5 | \n",
" 2204 | \n",
" нет | \n",
"
\n",
" \n",
"
\n",
"
1200 rows × 7 columns
\n",
"
"
],
"text/plain": [
" id gender ftype height score expenses wish\n",
"0 1 female пихта Нобилис 190 3 1051 да\n",
"1 2 male пихта Нобилис 174 3 2378 нет\n",
"2 3 female сосна Крым 248 4 655 да\n",
"3 4 female сосна Крым 191 1 2934 да\n",
"4 5 female сосна Крым 147 3 1198 нет\n",
"... ... ... ... ... ... ... ...\n",
"1195 1196 male ель обыкновенная 137 2 1298 нет\n",
"1196 1197 female пихта Нобилис 141 3 906 да\n",
"1197 1198 male сосна Крым 220 5 1591 нет\n",
"1198 1199 male сосна датская 94 1 1966 да\n",
"1199 1200 male сосна датская 105 5 2204 нет\n",
"\n",
"[1200 rows x 7 columns]"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.rename(columns = {\"Unnamed: 0\": \"id\"}) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Метод `.rename()` по умолчанию работает со строками, поэтому необходимо явно указать, что изменения применяются к столбцам – аргумент `columns`. Далее в качестве значения этого аргумента запишем словарь, где ключом будет старое название столбца, а значением – новое название столбца. \n",
"\n",
"Посмотрим теперь на первые несколько строк в `tree`:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Unnamed: 0 gender ftype height score expenses wish\n",
"0 1 female пихта Нобилис 190 3 1051 да\n",
"1 2 male пихта Нобилис 174 3 2378 нет\n",
"2 3 female сосна Крым 248 4 655 да\n",
"3 4 female сосна Крым 191 1 2934 да\n",
"4 5 female сосна Крым 147 3 1198 нет"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.head() "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Столбец не переименовался! Почему? Потому что многие методы в `pandas` не сохраняют изменения в исходном датафрейме, а возвращают копию датафрейма с внесенными изменениями, чтобы пользователь не мог случайно «испортить» датафрейм. Чтобы сохранить изменения, нужно дописать опцию `inplace=True` (записать изменения «на место» старых данных):"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id gender ftype height score expenses wish\n",
"0 1 female пихта Нобилис 190 3 1051 да\n",
"1 2 male пихта Нобилис 174 3 2378 нет\n",
"2 3 female сосна Крым 248 4 655 да\n",
"3 4 female сосна Крым 191 1 2934 да\n",
"4 5 female сосна Крым 147 3 1198 нет"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# теперь все ок\n",
"tree.rename(columns = {\"Unnamed: 0\": \"id\"}, inplace = True) \n",
"tree.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Внимание:** датафрейм является изменяемым типом данных (как и список). То есть, если понадобится создать копию датафрейма для тестирования всякого рода изменений, ее нужно будет создавать через метод `.copy()`. Запись вида `df2 = df1` создаст не копию датафрейма `df1`, а лишь ссылку на него, поэтому при изменении `df2` датафрейм `df1` тоже изменится."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Добавление новых столбцов"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Так как отдельный столбец датафрейма является объектом типа *pandas Series*, который наследует свойства массива, выполнять операции над столбцами довольно просто. Например, мы хотим добавить в `tree` столбец с высотой елки в метрах. Для этого достаточно выбрать столбец `height` и поделить все его значения на 100:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 1.90\n",
"1 1.74\n",
"2 2.48\n",
"3 1.91\n",
"4 1.47\n",
" ... \n",
"1195 1.37\n",
"1196 1.41\n",
"1197 2.20\n",
"1198 0.94\n",
"1199 1.05\n",
"Name: height, Length: 1200, dtype: float64"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[\"height\"] / 100"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь запишем полученный результат в новый столбец `height_m` датафрейма `tree`:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"tree[\"height_m\"] = tree[\"height\"] / 100"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
" height_m | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
" 1.90 | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
" 1.74 | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
" 2.48 | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
" 1.91 | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
" 1.47 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id gender ftype height score expenses wish height_m\n",
"0 1 female пихта Нобилис 190 3 1051 да 1.90\n",
"1 2 male пихта Нобилис 174 3 2378 нет 1.74\n",
"2 3 female сосна Крым 248 4 655 да 2.48\n",
"3 4 female сосна Крым 191 1 2934 да 1.91\n",
"4 5 female сосна Крым 147 3 1198 нет 1.47"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree.head() "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"По умолчанию новые столбцы записываются в конец датафрейма, но при желании столбцы можно упорядочить по своему желанию. \n",
"\n",
"**Пример:** в некотором датафрейме `df` есть столбцы `a`, `b`, `c`, мы хотим, поменять их местами так, чтобы сначала был `c`, потом `a`, а потом `b`:\n",
" \n",
" cols = ['c', 'a', 'b']\n",
" df = df[cols]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь рассмотрим случай посложнее. Допустим, мы хотим добавить новый столбец `comment`, который будет содержать текстовые комментарии на каждое значение из `score`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Напишем функцию `trans_comm()`, которая будет на каждое значение `score` возвращать текстовый комментарий:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"def trans_comm(x):\n",
" if x == 5:\n",
" r = \"excellent\"\n",
" elif x == 4:\n",
" r = \"good\"\n",
" elif x == 3:\n",
" r = \"not bad\"\n",
" elif x == 2:\n",
" r = \"bad\"\n",
" elif x == 1:\n",
" r = \"really firtree?\"\n",
" else:\n",
" r = None\n",
" return r"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь применим эту функцию к столбцу `score`. Метод `.apply()` работает так: пишем функцию как будто бы для значения в одной ячейке столбца, а потом применяем ее ко всему столбцу. Применяем и добавляем новый столбец `comment`:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" gender | \n",
" ftype | \n",
" height | \n",
" score | \n",
" expenses | \n",
" wish | \n",
" height_m | \n",
" comment | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" female | \n",
" пихта Нобилис | \n",
" 190 | \n",
" 3 | \n",
" 1051 | \n",
" да | \n",
" 1.90 | \n",
" not bad | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" male | \n",
" пихта Нобилис | \n",
" 174 | \n",
" 3 | \n",
" 2378 | \n",
" нет | \n",
" 1.74 | \n",
" not bad | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" сосна Крым | \n",
" 248 | \n",
" 4 | \n",
" 655 | \n",
" да | \n",
" 2.48 | \n",
" good | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" female | \n",
" сосна Крым | \n",
" 191 | \n",
" 1 | \n",
" 2934 | \n",
" да | \n",
" 1.91 | \n",
" really firtree? | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" female | \n",
" сосна Крым | \n",
" 147 | \n",
" 3 | \n",
" 1198 | \n",
" нет | \n",
" 1.47 | \n",
" not bad | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id gender ftype height score expenses wish height_m \\\n",
"0 1 female пихта Нобилис 190 3 1051 да 1.90 \n",
"1 2 male пихта Нобилис 174 3 2378 нет 1.74 \n",
"2 3 female сосна Крым 248 4 655 да 2.48 \n",
"3 4 female сосна Крым 191 1 2934 да 1.91 \n",
"4 5 female сосна Крым 147 3 1198 нет 1.47 \n",
"\n",
" comment \n",
"0 not bad \n",
"1 not bad \n",
"2 good \n",
"3 really firtree? \n",
"4 not bad "
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tree[\"comment\"] = tree[\"score\"].apply(trans_comm)\n",
"tree.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Удаление пропущенных значений\n",
"\n",
"Мы уже видели, что в данном датафрейме есть строки (и столбцы) с пропущенными значениями (`NaN`). \n",
"\n",
"**Полезное примечание:** Из-за наличия этих таких значений содержащие их столбцы, даже если остальные значения являются целыми, имеют тип `float`.\n",
"\n",
"Удалим строки с пропущенными значениями из датафрейма совсем:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"# inplace = True – сохраняем значения\n",
"tree.dropna(inplace=True)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}