- Таблицы pandas #
- Создание таблицы#
- Список списков или двухмерный массив NumPy #
- Словарь#
- По столбцам#
- По строкам#
- Чтение таблиц с жесткого диска#
- Индексация#
- Строки#
- Столбцы#
- Конкретные ячейки#
- Добавление столбцов#
- Pandas: как создать пустой фрейм данных с именами столбцов
- Пример 1: создание DataFrame с именами столбцов и без строк
- Пример 2: создание DataFrame с именами столбцов и определенным количеством строк
- Дополнительные ресурсы
Таблицы pandas #
pandas.DataFrame — по сути дела таблица, на которую можно смотреть как на объединение столбцов pandas.Series с выравниванием по общему индексу.
import pandas as pd s1 = pd.Series( "a": 1, "b": 2 >, dtype="Int8") s2 = pd.Series( "b": "two", "c": "three" >) df = pd.DataFrame( "s1": s1, "s2": s2 >) df
Таблицы изменяемы с точки зрения содержимого их ячеек, но лишь частично изменяемы с точки зрения размера: добавлять на месте можно только столбцы, но не строки.
Создание таблицы#
Как и в случае со столбцами, есть множество способов создать таблицу pandas из уже существующих объектов python . Большинство из них опираются на конструктор pandas.DataFrame.
Список списков или двухмерный массив NumPy #
Если ваши данные хранятся в виде списка списков, то на выходе каждый вложенный список будет соответствовать строке таблице.
data = [ ["a11", "a12", "a13"], ["a21", "a22", "a23"] ] df = pd.DataFrame(data) df
По умолчанию генерируется RangeIndex и для строк и для столбцов таблицы.
df.index=RangeIndex(start=0, stop=2, step=1), df.columns=RangeIndex(start=0, stop=3, step=1)
Опциональными параметрами конструктора columns и index можно указать пользовательские значения.
df = pd.DataFrame(data, columns=["column 1", "column 2", "column 3"], index=["row 1", "row 2"]) df
Если вместо списка списков передавать двухмерный массив NumPy , то все будет работать точно также, кроме возможной потери типов.
import numpy as np data = np.array(data) df = pd.DataFrame(data, columns=["column 1", "column 2", "column 3"], index=["row 1", "row 2"]) df
Словарь#
Один самых удобных способов создавать таблицу в pandas — использовать словари.
Тут возможно два варианта.
- ключи словаря — названия столбца, значение по ключу — содержимое соответствующего столбца;
- ключи словаря — метки строк, значение по ключу — содержимое соответствующей строки.
По столбцам#
Первый вариант гораздо более распространен, поэтому его рассмотрим первым. Итак, ключи словаря станут названиями столбцов, значение по ключу — станет содержимым с соответствующим значением.
Будущие столбцы в словари могут быть представлены списком, массивом NumPy , а также столбцом pandas . При этом в случае списков и массивов NumPy накладывается требование на одинаковую длину всех столбцов, а также автоматически генерируется RangeIndex, если он не указан в явном виде опциональным параметром index .
col1 = np.array(["a11", "a21"]) col2 = ["a21", "a22"] col3 = "a31", "a32" d = "column 1": col1, "column 2": col2, "column 3": col3 > df = pd.DataFrame(d, index=["a", "b"]) df
Если же содержимое будущих столбцов представлено в виде столбцов pandas , то индекс таблицы генерируется из индексов этих столбцов, а ограничение на одинаковую длину столбцов снимается: строки таблицы выравниваются по индексу.
import pandas as pd import numpy as np col1 = pd.Series([1, 2], index=["a", "b"]) col2 = pd.Series([3, 4], index=["b", "a"], dtype="Int64") col3 = pd.Series([5, 6, 7], index=["a", "b", "c"]) d = 'column 1': col1, 'column 2': col2, 'column 3': col3, > df = pd.DataFrame(d) df
По строкам#
Статический метод pandas.DataFrame.form_dict — более специализированный метод для создания таблицы из словаря. В примерах из предыдущего раздела этот метод сработает точно также, как и базовый конструктор класса, но наличие дополнительного опционального параметра orient ( orientation ) позволяет создавать таблицу из строк.
Если указать в качестве orient строку index , то ключи словаря будут восприниматься в качестве меток строк, а значение по ключу — содержимое строки с соответствующей меткой. Все остальное продолжает работать также, но с заменой меток и названий столбцов местами.
row1 = pd.Series([1, 2], index=["column 1", "column 2"]) row2 = pd.Series([3, 4], index=["column 2", "column 1"]) d = "row1": row1, "row2": row2, > pd.DataFrame.from_dict(d, orient="index")
Чтение таблиц с жесткого диска#
Библиотека pandas позволяет свободно оперировать с таблицами в формате csv , json , таблицами excel (потребуется установка дополнительной библиотеки, например, openpyxl), а также более продвинутыми бинарными форматами hdf5, apache parquet и многими другими форматами. Формат csv — один из самых простых и распространенных в научной среде, поэтому рассмотрим чтение таблиц средствами pandas именно на его примере.
Все таблицы из этой лекции хранятся в репозитории с исходниками этого ресурса в папке по ссылке.
Предположим следующее содержимое хранится в текстовом файле planets.csv со следующим содержимым.
Название,Количество спутников,Масса,Группа,Кольца Меркурий,0,0.0055,земная группа,Нет Венера,0,0.815,земная группа,Нет Земля,1,1.0,земная группа,Нет Марс,2,0.107,земная группа,Нет Юпитер,62,317.8,газовый гигант,Да Сатурн,34,95.2,газовый гигант,Да Уран,27,14.37,ледяной гигант,Да Нептун,13,17.15,ледяной гигант,Да
Для чтения такой таблицы используется метод read_csv.
import os path = os.path.join("..", "..", "assets", "data", "tables", "planets.csv") planets = pd.read_csv(path) print(planets.info()) planets.head()
RangeIndex: 8 entries, 0 to 7 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Название 8 non-null object 1 Количество спутников 8 non-null int64 2 Масса 8 non-null float64 3 Группа 8 non-null object 4 Кольца 8 non-null object dtypes: float64(1), int64(1), object(3) memory usage: 448.0+ bytes None
Название | Количество спутников | Масса | Группа | Кольца | |
---|---|---|---|---|---|
0 | Меркурий | 0 | 0.0055 | земная группа | Нет |
1 | Венера | 0 | 0.8150 | земная группа | Нет |
2 | Земля | 1 | 1.0000 | земная группа | Нет |
3 | Марс | 2 | 0.1070 | земная группа | Нет |
4 | Юпитер | 62 | 317.8000 | газовый гигант | Да |
В самом простом варианте использования функции read_csv
- имена столбцов распознаются из первой строки файла (параметром header можно повлиять на это);
- в качестве индекса генерируется RangeIndex (параметром index_col можно выбрать столбец индекса таблицы);
- в качестве разделителя ожидается символ запятой “ , ” (параметром sep можно на это повлиять);
- пропущенные значения заполняются значением “ np.nan ” (параметром na_values можно указать, какие ещё значения интерпретировать, как пропущенные);
- столбцы с датами не распознаются (смотри страницу “ Дата и время ”).
Метод DataFrame.head возвращает первые n строк таблицы. По умолчанию n равно 5, но можно указать явно и другое значение. Похожий по смыслу метод DataFrame.tail возвращает последние n строк.
Метод DataFrame.info печатает информацию о таблице. В частности, из вывода этой функции можно понять количество строк и столбцов, тип индекса таблицы, имя каждого столбца, тип данных и количество непропущенных значений в них.
Считаем эту таблицу ещё раз, указав в этот раз в качестве индекса столбец «Название» .
planets = pd.read_csv(path, index_col="Название", sep=",") planets
Количество спутников | Масса | Группа | Кольца | |
---|---|---|---|---|
Название | ||||
Меркурий | 0 | 0.0055 | земная группа | Нет |
Венера | 0 | 0.8150 | земная группа | Нет |
Земля | 1 | 1.0000 | земная группа | Нет |
Марс | 2 | 0.1070 | земная группа | Нет |
Юпитер | 62 | 317.8000 | газовый гигант | Да |
Сатурн | 34 | 95.2000 | газовый гигант | Да |
Уран | 27 | 14.3700 | ледяной гигант | Да |
Нептун | 13 | 17.1500 | ледяной гигант | Да |
Аналогично можно считывать данные из таблиц excel методом read_excel.
Методами to_csv и to_excel можно сохранить DataFrame в таблицу удобном формате (для сохранения в excel необходимо поставить библиотеку openpyxl или её аналоги).
Индексация#
Строки#
Для получения строк таблицы используются те же самые .loc и iloc (метки и порядковый номер соответственно).
print(planets.loc["Марс"]) print("_" * 80) print(planets.iloc[2])
Количество спутников 2 Масса 0.107 Группа земная группа Кольца Нет Name: Марс, dtype: object ________________________________________________________________________________ Количество спутников 1 Масса 1.0 Группа земная группа Кольца Нет Name: Земля, dtype: object
В ответ вы получаете объект pandas.Series соответствующей всей строке, при этом индекс этого объекта соответствует названиям столбцов. Если использовать срезы или список меток, то вы получите новую таблицу с, возможно, меньшим количеством строк.
Простые квадратные скобки “ [] ” не индексируют таблицу по строкам!
Столбцы#
Для получения столбца используется оператор “ [] ”.
planets["Количество спутников"]
Название Меркурий 0 Венера 0 Земля 1 Марс 2 Юпитер 62 Сатурн 34 Уран 27 Нептун 13 Name: Количество спутников, dtype: int64
Если в названии столбца нет пробелов и оно не совпадает ни с одним методом класса pandas.DataFrame , то можно использовать точечную нотацию. Хотя, конечно, в случае кириллицы это выглядит странно.
Название Меркурий 0.0055 Венера 0.8150 Земля 1.0000 Марс 0.1070 Юпитер 317.8000 Сатурн 95.2000 Уран 14.3700 Нептун 17.1500 Name: Масса, dtype: float64
Можно указывать список названий столбцов, чтобы извлечь сразу подтаблицу целиком.
planets[["Группа", "Кольца", "Масса"]]
Группа | Кольца | Масса | |
---|---|---|---|
Название | |||
Меркурий | земная группа | Нет | 0.0055 |
Венера | земная группа | Нет | 0.8150 |
Земля | земная группа | Нет | 1.0000 |
Марс | земная группа | Нет | 0.1070 |
Юпитер | газовый гигант | Да | 317.8000 |
Сатурн | газовый гигант | Да | 95.2000 |
Уран | ледяной гигант | Да | 14.3700 |
Нептун | ледяной гигант | Да | 17.1500 |
Конкретные ячейки#
Для получения доступа сразу к конкретной ячейке используются методы DataFrame.at и DataFrame.iat.
- метод DataFrame.at принимает на вход метку строки и название столбца, и возвращает значение ячейки, располагающейся на их пересечении.
- метод DataFrame.iat принимает на вход номер строки и номер столбца, и возвращает значение ячейки, располагающейся на их пересечении.
print(f"planets.at['Меркурий', 'Количество спутников']=>, planets.iat[0, 0]=>")
planets.at['Меркурий', 'Количество спутников']=0, planets.iat[0, 0]=0
Однако, если метки строк и названия столбцов повторяются, то методом “ .at ” вместо значения одной ячейки вы можете получить или сразу pandas.Series или pandas.DataFrame .
duplicated_df = pd.DataFrame(data=[[1, 1], [1, 1]], index=["a", "a"], columns=["b", "b"]) duplicated_df
Добавление столбцов#
Добавление и изменение столбцов в таблицу похоже на добавление элементов в словарь. При этом данные автоматически выравниваются по индексу. В качестве примера добавим к таблице про планет столбец с данными про экваториальный диаметр. Обратите внимание, что планеты перечислены в порядке отличном от порядка таблицы, и далеко не все планеты есть в новом столбце. В итоговой таблицы все присутствующие значения выравниваются, а недостающие заменяются на NaN .
planets["Экваториальный диаметр"] = pd.Series( "Венера": 0.949, "Сатурн": 9.449, "Земля": 1.0, "Меркурий": 0.382, >) planets
Количество спутников | Масса | Группа | Кольца | Экваториальный диаметр | |
---|---|---|---|---|---|
Название | |||||
Меркурий | 0 | 0.0055 | земная группа | Нет | 0.382 |
Венера | 0 | 0.8150 | земная группа | Нет | 0.949 |
Земля | 1 | 1.0000 | земная группа | Нет | 1.000 |
Марс | 2 | 0.1070 | земная группа | Нет | NaN |
Юпитер | 62 | 317.8000 | газовый гигант | Да | NaN |
Сатурн | 34 | 95.2000 | газовый гигант | Да | 9.449 |
Уран | 27 | 14.3700 | ледяной гигант | Да | NaN |
Нептун | 13 | 17.1500 | ледяной гигант | Да | NaN |
Pandas: как создать пустой фрейм данных с именами столбцов
Вы можете использовать следующий базовый синтаксис для создания пустого кадра данных pandas с определенными именами столбцов:
df = pd.DataFrame(columns=['Col1', 'Col2', 'Col3'])
В следующих примерах показано, как использовать этот синтаксис на практике.
Пример 1: создание DataFrame с именами столбцов и без строк
В следующем коде показано, как создать кадр данных pandas с определенными именами столбцов и без строк:
import pandas as pd #create DataFrame df = pd.DataFrame(columns=['A', 'B', 'C', 'D', 'E']) #view DataFrame df A B C D E
Мы можем использовать форму , чтобы получить размер DataFrame:
#display shape of DataFrame df.shape (0, 5)
Это говорит нам о том, что DataFrame имеет 0 строк и 5 столбцов.
Мы также можем использовать list() для получения списка имен столбцов:
#display list of column names list(df) ['A', 'B', 'C', 'D', 'E']
Пример 2: создание DataFrame с именами столбцов и определенным количеством строк
В следующем коде показано, как создать кадр данных pandas с определенными именами столбцов и определенным количеством строк:
import pandas as pd #create DataFrame df = pd.DataFrame(columns=['A', 'B', 'C', 'D', 'E'], index=range(1, 10)) #view DataFrame df A B C D E 1 NaN NaN NaN NaN NaN 2 NaN NaN NaN NaN NaN 3 NaN NaN NaN NaN NaN 4 NaN NaN NaN NaN NaN 5 NaN NaN NaN NaN NaN 6 NaN NaN NaN NaN NaN 7 NaN NaN NaN NaN NaN 8 NaN NaN NaN NaN NaN 9 NaN NaN NaN NaN NaN
Обратите внимание, что каждое значение в DataFrame заполнено значением NaN.
Еще раз, мы можем использовать форму , чтобы получить размер DataFrame:
#display shape of DataFrame df.shape (9, 5)
Это говорит нам о том, что DataFrame имеет 9 строк и 5 столбцов.
Дополнительные ресурсы
В следующих руководствах объясняется, как выполнять другие распространенные операции в pandas: