{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Таблицы `pandas`\n", "\n", "[pandas.DataFrame](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) --- по сути дела таблица, на которую можно смотреть как на объединение столбцов `pandas.Series` с выравниванием по общему индексу. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
s1s2
a1NaN
b2two
c<NA>three
\n", "
" ], "text/plain": [ " s1 s2\n", "a 1 NaN\n", "b 2 two\n", "c three" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "\n", "s1 = pd.Series({\n", " \"a\": 1,\n", " \"b\": 2\n", "}, dtype=\"Int8\")\n", "s2 = pd.Series({\n", " \"b\": \"two\",\n", " \"c\": \"three\"\n", "})\n", "\n", "df = pd.DataFrame({\n", " \"s1\": s1,\n", " \"s2\": s2\n", "})\n", "\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Таблицы изменяемы с точки зрения содержимого их ячеек, но лишь частично изменяемы с точки зрения размера: добавлять на месте можно только столбцы, но не строки. \n", "\n", "## Создание таблицы\n", "\n", "Как и в случае со столбцами, есть множество способов создать таблицу `pandas` из уже существующих объектов `python`. Большинство из них опираются на конструктор [pandas.DataFrame](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html).\n", "\n", "### Список списков или двухмерный массив `NumPy`\n", "\n", "Если ваши данные хранятся в виде списка списков, то на выходе каждый вложенный список будет соответствовать строке таблице." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
0a11a12a13
1a21a22a23
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 a11 a12 a13\n", "1 a21 a22 a23" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = [\n", " [\"a11\", \"a12\", \"a13\"],\n", " [\"a21\", \"a22\", \"a23\"]\n", " ]\n", "\n", "df = pd.DataFrame(data)\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "По умолчанию генерируется [RangeIndex](https://pandas.pydata.org/docs/reference/api/pandas.RangeIndex.html) и для строк и для столбцов таблицы. " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "df.index=RangeIndex(start=0, stop=2, step=1), df.columns=RangeIndex(start=0, stop=3, step=1)\n" ] } ], "source": [ "print(f\"{df.index=}, {df.columns=}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Опциональными параметрами конструктора `columns` и `index` можно указать пользовательские значения." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
column 1column 2column 3
row 1a11a12a13
row 2a21a22a23
\n", "
" ], "text/plain": [ " column 1 column 2 column 3\n", "row 1 a11 a12 a13\n", "row 2 a21 a22 a23" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(data, columns=[\"column 1\", \"column 2\", \"column 3\"], index=[\"row 1\", \"row 2\"])\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если вместо списка списков передавать двухмерный массив `NumPy`, то все будет работать точно также, кроме возможной потери типов." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
column 1column 2column 3
row 1a11a12a13
row 2a21a22a23
\n", "
" ], "text/plain": [ " column 1 column 2 column 3\n", "row 1 a11 a12 a13\n", "row 2 a21 a22 a23" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "data = np.array(data)\n", "df = pd.DataFrame(data, columns=[\"column 1\", \"column 2\", \"column 3\"], index=[\"row 1\", \"row 2\"])\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Словарь\n", "\n", "Один самых удобных способов создавать таблицу в `pandas` --- использовать словари. \n", "\n", "Тут возможно два варианта.\n", "1. ключи словаря --- названия столбца, значение по ключу --- содержимое соответствующего столбца;\n", "2. ключи словаря --- метки строк, значение по ключу --- содержимое соответствующей строки. \n", "\n", "#### По столбцам\n", "\n", "Первый вариант гораздо более распространен, поэтому его рассмотрим первым. Итак, ключи словаря станут названиями столбцов, значение по ключу --- станет содержимым с соответствующим значением. \n", "\n", "Будущие столбцы в словари могут быть представлены списком, массивом `NumPy`, а также столбцом `pandas`. При этом в случае списков и массивов `NumPy` накладывается требование на одинаковую длину всех столбцов, а также автоматически генерируется [RangeIndex](https://pandas.pydata.org/docs/reference/api/pandas.RangeIndex.html), если он не указан в явном виде опциональным параметром `index`." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
column 1column 2column 3
aa11a21a31
ba21a22a32
\n", "
" ], "text/plain": [ " column 1 column 2 column 3\n", "a a11 a21 a31\n", "b a21 a22 a32" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "col1 = np.array([\"a11\", \"a21\"])\n", "col2 = [\"a21\", \"a22\"]\n", "col3 = \"a31\", \"a32\"\n", "\n", "d = {\n", " \"column 1\": col1,\n", " \"column 2\": col2,\n", " \"column 3\": col3\n", "}\n", "\n", "df = pd.DataFrame(d, index=[\"a\", \"b\"])\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если же содержимое будущих столбцов представлено в виде столбцов `pandas`, то индекс таблицы генерируется из индексов этих столбцов, а ограничение на одинаковую длину столбцов снимается: строки таблицы выравниваются по индексу." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
column 1column 2column 3
a1.045
b2.036
cNaN<NA>7
\n", "
" ], "text/plain": [ " column 1 column 2 column 3\n", "a 1.0 4 5\n", "b 2.0 3 6\n", "c NaN 7" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "import numpy as np\n", "\n", "col1 = pd.Series([1, 2], index=[\"a\", \"b\"])\n", "col2 = pd.Series([3, 4], index=[\"b\", \"a\"], dtype=\"Int64\")\n", "col3 = pd.Series([5, 6, 7], index=[\"a\", \"b\", \"c\"])\n", "\n", "d = {\n", " 'column 1': col1, \n", " 'column 2': col2,\n", " 'column 3': col3,\n", "}\n", "\n", "df = pd.DataFrame(d)\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### По строкам \n", "\n", "Статический метод [pandas.DataFrame.form_dict](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.from_dict.html#pandas.DataFrame.from_dict) --- более специализированный метод для создания таблицы из словаря. В примерах из предыдущего раздела этот метод сработает точно также, как и базовый конструктор класса, но наличие дополнительного опционального параметра `orient` (`orientation`) позволяет создавать таблицу из строк. \n", "\n", "Если указать в качестве `orient` строку `index`, то ключи словаря будут восприниматься в качестве меток строк, а значение по ключу --- содержимое строки с соответствующей меткой. Все остальное продолжает работать также, но с заменой меток и названий столбцов местами." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
column 1column 2
row112
row243
\n", "
" ], "text/plain": [ " column 1 column 2\n", "row1 1 2\n", "row2 4 3" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "row1 = pd.Series([1, 2], index=[\"column 1\", \"column 2\"])\n", "row2 = pd.Series([3, 4], index=[\"column 2\", \"column 1\"])\n", "\n", "d = {\n", " \"row1\": row1,\n", " \"row2\": row2,\n", "}\n", "\n", "pd.DataFrame.from_dict(d, orient=\"index\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Чтение таблиц с жесткого диска \n", "\n", "Библиотека `pandas` позволяет свободно оперировать с таблицами в формате `csv`, `json`, таблицами `excel` (потребуется установка дополнительной библиотеки, например, [openpyxl](https://openpyxl.readthedocs.io/en/stable/)), а также более продвинутыми бинарными форматами [hdf5](https://en.wikipedia.org/wiki/Hierarchical_Data_Format#HDF5), [apache parquet](https://parquet.apache.org/docs/) и многими другими форматами. Формат `csv` --- один из самых простых и распространенных в научной среде, поэтому рассмотрим чтение таблиц средствами `pandas` именно на его примере.\n", "\n", "```{note}\n", "Все таблицы из этой лекции хранятся в репозитории с исходниками этого ресурса в папке по [ссылке](https://github.com/FadeevLecturer/python_lectures/tree/main/assets/data/tables). \n", "```\n", "\n", "Предположим следующее содержимое хранится в текстовом файле `planets.csv` со следующим содержимым. \n", "\n", "```\n", "Название,Количество спутников,Масса,Группа,Кольца\n", "Меркурий,0,0.0055,земная группа,Нет\n", "Венера,0,0.815,земная группа,Нет\n", "Земля,1,1.0,земная группа,Нет\n", "Марс,2,0.107,земная группа,Нет\n", "Юпитер,62,317.8,газовый гигант,Да \n", "Сатурн,34,95.2,газовый гигант,Да\n", "Уран,27,14.37,ледяной гигант,Да\n", "Нептун,13,17.15,ледяной гигант,Да\n", "```\n", "\n", "Для чтения такой таблицы используется метод [read_csv](https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html). " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 8 entries, 0 to 7\n", "Data columns (total 5 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 Название 8 non-null object \n", " 1 Количество спутников 8 non-null int64 \n", " 2 Масса 8 non-null float64\n", " 3 Группа 8 non-null object \n", " 4 Кольца 8 non-null object \n", "dtypes: float64(1), int64(1), object(3)\n", "memory usage: 448.0+ bytes\n", "None\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
НазваниеКоличество спутниковМассаГруппаКольца
0Меркурий00.0055земная группаНет
1Венера00.8150земная группаНет
2Земля11.0000земная группаНет
3Марс20.1070земная группаНет
4Юпитер62317.8000газовый гигантДа
\n", "
" ], "text/plain": [ " Название Количество спутников Масса Группа Кольца\n", "0 Меркурий 0 0.0055 земная группа Нет\n", "1 Венера 0 0.8150 земная группа Нет\n", "2 Земля 1 1.0000 земная группа Нет\n", "3 Марс 2 0.1070 земная группа Нет\n", "4 Юпитер 62 317.8000 газовый гигант Да " ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import os\n", "path = os.path.join(\"..\", \"..\", \"assets\", \"data\", \"tables\", \"planets.csv\")\n", "\n", "planets = pd.read_csv(path)\n", "print(planets.info())\n", "planets.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В самом простом варианте использования функции `read_csv` \n", "- имена столбцов распознаются из первой строки файла (параметром `header` можно повлиять на это);\n", "- в качестве индекса генерируется `RangeIndex` (параметром `index_col` можно выбрать столбец индекса таблицы);\n", "- в качестве разделителя ожидается символ запятой \"`,`\" (параметром `sep` можно на это повлиять);\n", "- пропущенные значения заполняются значением \"`np.nan`\" (параметром `na_values` можно указать, какие ещё значения интерпретировать, как пропущенные);\n", "- столбцы с датами не распознаются (смотри страницу \"[](datetime)\").\n", "\n", "```{note}\n", "Метод [DataFrame.head](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.head.html) возвращает первые `n` строк таблицы. По умолчанию `n` равно 5, но можно указать явно и другое значение. Похожий по смыслу метод [DataFrame.tail](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.tail.html) возвращает последние `n` строк.\n", "\n", "Метод [DataFrame.info](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.info.html) печатает информацию о таблице. В частности, из вывода этой функции можно понять количество строк и столбцов, тип индекса таблицы, имя каждого столбца, тип данных и количество непропущенных значений в них.\n", "```\n", "\n", "Считаем эту таблицу ещё раз, указав в этот раз в качестве индекса столбец `\"Название\"`." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Количество спутниковМассаГруппаКольца
Название
Меркурий00.0055земная группаНет
Венера00.8150земная группаНет
Земля11.0000земная группаНет
Марс20.1070земная группаНет
Юпитер62317.8000газовый гигантДа
Сатурн3495.2000газовый гигантДа
Уран2714.3700ледяной гигантДа
Нептун1317.1500ледяной гигантДа
\n", "
" ], "text/plain": [ " Количество спутников Масса Группа Кольца\n", "Название \n", "Меркурий 0 0.0055 земная группа Нет\n", "Венера 0 0.8150 земная группа Нет\n", "Земля 1 1.0000 земная группа Нет\n", "Марс 2 0.1070 земная группа Нет\n", "Юпитер 62 317.8000 газовый гигант Да \n", "Сатурн 34 95.2000 газовый гигант Да\n", "Уран 27 14.3700 ледяной гигант Да\n", "Нептун 13 17.1500 ледяной гигант Да" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "planets = pd.read_csv(path, index_col=\"Название\", sep=\",\")\n", "planets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Аналогично можно считывать данные из таблиц `excel` методом [read_excel](https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html). \n", "\n", "Методами [to_csv](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html#pandas.DataFrame.to_csv) и [to_excel](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_excel.html#pandas.DataFrame.to_excel) можно сохранить `DataFrame` в таблицу удобном формате (для сохранения в `excel` необходимо поставить библиотеку [openpyxl](https://openpyxl.readthedocs.io/en/stable/) или её аналоги)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Индексация \n", "\n", "### Строки\n", "\n", "Для получения строк таблицы используются те же самые [.loc](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html) и [iloc](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html) (метки и порядковый номер соответственно). " ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Количество спутников 2\n", "Масса 0.107\n", "Группа земная группа\n", "Кольца Нет\n", "Name: Марс, dtype: object\n", "________________________________________________________________________________\n", "Количество спутников 1\n", "Масса 1.0\n", "Группа земная группа\n", "Кольца Нет\n", "Name: Земля, dtype: object\n" ] } ], "source": [ "print(planets.loc[\"Марс\"])\n", "print(\"_\" * 80)\n", "print(planets.iloc[2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В ответ вы получаете объект `pandas.Series` соответствующей всей строке, при этом индекс этого объекта соответствует названиям столбцов. Если использовать срезы или список меток, то вы получите новую таблицу с, возможно, меньшим количеством строк. \n", "\n", "```{warning}\n", "Простые квадратные скобки \"`[]`\" не индексируют таблицу по строкам!\n", "```\n", "\n", "### Столбцы\n", "\n", "Для получения столбца используется оператор \"`[]`\"." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Название\n", "Меркурий 0\n", "Венера 0\n", "Земля 1\n", "Марс 2\n", "Юпитер 62\n", "Сатурн 34\n", "Уран 27\n", "Нептун 13\n", "Name: Количество спутников, dtype: int64" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "planets[\"Количество спутников\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если в названии столбца нет пробелов и оно не совпадает ни с одним методом класса `pandas.DataFrame`, то можно использовать точечную нотацию. Хотя, конечно, в случае кириллицы это выглядит странно. " ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Название\n", "Меркурий 0.0055\n", "Венера 0.8150\n", "Земля 1.0000\n", "Марс 0.1070\n", "Юпитер 317.8000\n", "Сатурн 95.2000\n", "Уран 14.3700\n", "Нептун 17.1500\n", "Name: Масса, dtype: float64" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "planets.Масса" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Можно указывать список названий столбцов, чтобы извлечь сразу подтаблицу целиком. " ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ГруппаКольцаМасса
Название
Меркурийземная группаНет0.0055
Венераземная группаНет0.8150
Земляземная группаНет1.0000
Марсземная группаНет0.1070
Юпитергазовый гигантДа317.8000
Сатурнгазовый гигантДа95.2000
Уранледяной гигантДа14.3700
Нептунледяной гигантДа17.1500
\n", "
" ], "text/plain": [ " Группа Кольца Масса\n", "Название \n", "Меркурий земная группа Нет 0.0055\n", "Венера земная группа Нет 0.8150\n", "Земля земная группа Нет 1.0000\n", "Марс земная группа Нет 0.1070\n", "Юпитер газовый гигант Да 317.8000\n", "Сатурн газовый гигант Да 95.2000\n", "Уран ледяной гигант Да 14.3700\n", "Нептун ледяной гигант Да 17.1500" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "planets[[\"Группа\", \"Кольца\", \"Масса\"]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Конкретные ячейки" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для получения доступа сразу к конкретной ячейке используются методы [DataFrame.at](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.at.html) и [DataFrame.iat](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.iat.html#pandas.DataFrame.iat).\n", "- метод [DataFrame.at](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.at.html) принимает на вход метку строки и название столбца, и возвращает значение ячейки, располагающейся на их пересечении.\n", "- метод [DataFrame.iat](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.iat.html) принимает на вход номер строки и номер столбца, и возвращает значение ячейки, располагающейся на их пересечении." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "planets.at['Меркурий', 'Количество спутников']=0, planets.iat[0, 0]=0\n" ] } ], "source": [ "print(f\"{planets.at['Меркурий', 'Количество спутников']=}, {planets.iat[0, 0]=}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Однако, если метки строк и названия столбцов повторяются, то методом \"`.at`\" вместо значения одной ячейки вы можете получить или сразу `pandas.Series` или `pandas.DataFrame`." ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
bb
a11
a11
\n", "
" ], "text/plain": [ " b b\n", "a 1 1\n", "a 1 1" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "duplicated_df = pd.DataFrame(data=[[1, 1], [1, 1]], index=[\"a\", \"a\"], columns=[\"b\", \"b\"])\n", "duplicated_df" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
bb
a11
a11
\n", "
" ], "text/plain": [ " b b\n", "a 1 1\n", "a 1 1" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "duplicated_df.at[\"a\", \"b\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Добавление столбцов \n", "\n", "Добавление и изменение столбцов в таблицу похоже на добавление элементов в словарь. При этом данные автоматически выравниваются по индексу. В качестве примера добавим к таблице про планет столбец с данными про экваториальный диаметр. Обратите внимание, что планеты перечислены в порядке отличном от порядка таблицы, и далеко не все планеты есть в новом столбце. В итоговой таблицы все присутствующие значения выравниваются, а недостающие заменяются на `NaN`." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Количество спутниковМассаГруппаКольцаЭкваториальный диаметр
Название
Меркурий00.0055земная группаНет0.382
Венера00.8150земная группаНет0.949
Земля11.0000земная группаНет1.000
Марс20.1070земная группаНетNaN
Юпитер62317.8000газовый гигантДаNaN
Сатурн3495.2000газовый гигантДа9.449
Уран2714.3700ледяной гигантДаNaN
Нептун1317.1500ледяной гигантДаNaN
\n", "
" ], "text/plain": [ " Количество спутников Масса Группа Кольца \\\n", "Название \n", "Меркурий 0 0.0055 земная группа Нет \n", "Венера 0 0.8150 земная группа Нет \n", "Земля 1 1.0000 земная группа Нет \n", "Марс 2 0.1070 земная группа Нет \n", "Юпитер 62 317.8000 газовый гигант Да \n", "Сатурн 34 95.2000 газовый гигант Да \n", "Уран 27 14.3700 ледяной гигант Да \n", "Нептун 13 17.1500 ледяной гигант Да \n", "\n", " Экваториальный диаметр \n", "Название \n", "Меркурий 0.382 \n", "Венера 0.949 \n", "Земля 1.000 \n", "Марс NaN \n", "Юпитер NaN \n", "Сатурн 9.449 \n", "Уран NaN \n", "Нептун NaN " ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "planets[\"Экваториальный диаметр\"] = pd.Series({\n", " \"Венера\": 0.949,\n", " \"Сатурн\": 9.449,\n", " \"Земля\": 1.0,\n", " \"Меркурий\": 0.382,\n", "})\n", "\n", "planets" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8.10 ('venv': venv)", "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.10.7" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "eea3ef54c04064aa17c056cc2578c78db8b44278034b77b7225a3166c34cea02" } } }, "nbformat": 4, "nbformat_minor": 2 }