Изучаем pandas. Урок 2. Структуры данных Series и DataFrame

Во втором уроке мы познакомимся со структурами данных pandas – это Series и DataFrame. Основное внимание будет уделено вопросам создания и получения доступа к элементам данных структур, а также общим понятиям, которые позволят более интуитивно работать с ними в будущем.

  1. Введение
  2. Структура данных Series
  3. Структура данных DataFrame

Введение

Библиотека pandas предоставляет две структуры: Series и DataFrame для быстрой и удобной работы с данными (на самом деле их три, есть еще одна структура – Panel, но в данный момент она находится в статусе deprecated и в будущем будет исключена из состава библиотеки pandas). Series – это маркированная одномерная структура данных, ее можно представить, как таблицу с одной строкой. С Series можно работать как с обычным массивом (обращаться по номеру индекса), и как с ассоциированным массивом, когда можно использовать ключ для доступа к элементам данных. DataFrame – это двумерная маркированная структура. Идейно она очень похожа на обычную таблицу, что выражается в способе ее создания и работе с ее элементами. Panel – про который было сказано, что он вскоре будет исключен из pandas, представляет собой трехмерную структуру данных. О Panel мы больше говорить не будем. В рамках этой части мы остановимся на вопросах создания и получения доступа к элементам данных структур Series и DataFrame.

Структура данных Series

Для того, чтобы начать работать со структурами данных из pandas требуется предварительно импортировать необходимые модули. Убедитесь, что нужные модули установлены на вашем компьютере, о том, как это сделать, можно прочитать в первой части данного курса. Также будем считать, что вы знакомы с языком Python. Если нет, то специально для вас мы подготовили он-лайн курс и книгу.

Помимо самого pandas нам понадобится библиотека numpy. Наши эксперименты будем проводить с использованием пакета Anaconda, в качестве среды разработки советуем взять Spyder, который входит в базовую поставку AnacondaДля того, чтобы запустить Spyder, перейдите в каталог Scripts, который находится в папке с установленной Anaconda и запустите spyder.exe. Для нас он в первую очередь имеет ценность в том, что в нем есть редактор исходного кода, на случай, если нам понадобится написать довольно большую программу, и интерпретатор для быстрых экспериментов. Если строки кода будут содержать префикс в виде цифры в квадратных скобках, то это означает, что данные команды мы вводим в интерпретаторе, в ином случае, это будет означать, что код написан в редакторе.

Пора переходить к практике!

Импортируем нужные нам библиотеки.

In [1]: import numpy as np
In [2]: import pandas as pd

Создать структуру Series можно на базе различных типов данных:

  • словари Python;
  • списки Python;
  • массивы из numpy: ndarray;
  • скалярные величины.

Конструктор класса Series выглядит следующим образом:

pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)

data – массив, словарь или скалярное значение, на базе которого будет построен Series;

index – список меток, который будет использоваться для доступа к элементам Series. Длина списка должна быть равна длине data;

dtype – объект numpy.dtype, определяющий тип данных;

copy – создает копию массива данных, если параметр равен True в ином случае ничего не делает.

В большинстве случаев, при создании Series, используют только первые два параметра. Рассмотрим различные варианты как это можно сделать.

Создание Series из списка Python

Самый простой способ создать Series – это передать в качестве единственного параметра в конструктор класса список Python.

In [3]: s1 = pd.Series([1, 2, 3, 4, 5])
In [4]: print(s1)
0 1
1 2
2 3
3 4
4 5
dtype: int64

В данном примере была создана структура Series на базе списка из языка Python. Для доступа к элементам Series, в данном случае, можно использовать только положительные целые числа – левый столбец чисел, начинающийся с нуля – это как раз и есть индексы элементов структуры, которые представлены в правом столбце.

Можно попробовать использоваться больше возможностей из тех, что предлагает pandas, для этого передадим в качестве второго элемента список строк (в нашем случае – это отдельные символы). Такой шаг позволит нам обращаться к элементам структуры Series не только по численному индексу, но и по метке, что сделает работу с таким объектом, похожей на работу со словарем.

In [5]: s2 = pd.Series([1, 2, 3, 4, 5], ['a', 'b', 'c', 'd', 'e'])
In [6]: print(s2)
a 1
b 2
c 3
d 4
e 5
dtype: int64

Обратите внимание на левый столбец, в нем содержатся метки, которые мы передали в качестве index параметра при создании структуры. Правый столбец – это по-прежнему элементы нашей структуры.

Создание Series из ndarray массива из numpy

Создадим простой массив из пяти чисел, аналогичный списку из предыдущего раздела. Библиотеки pandas и numpy должны быть предварительно импортированы.

In [3]: ndarr = np.array([1, 2, 3, 4, 5])
In [4]: type(ndarr)
Out[4]: numpy.ndarray

Теперь создадим Series с буквенными метками.

In [5]: s3 = pd.Series(ndarr, ['a', 'b', 'c', 'd', 'e'])
In [6]: print(s3)
a 1
b 2
c 3
d 4
e 5
dtype: int32

Создание Series из словаря (dict)

Еще один способ создать структуру Series – это использовать словарь для одновременного задания меток и значений.

In [7]: d = {'a':1, 'b':2, 'c':3}
In [8]: s4 = pd.Series(d)
In [9]: print(s4)
a 1
b 2
c 3
dtype: int64

Ключи (keys) из словаря d станут метками структуры s4, а значения (values) словаря – значениями в структуре.

Создание Series с использованием константы

Рассмотрим еще один способ создания структуры. На этот раз значения в ячейках структуры будут одинаковыми.

In [10]: a = 7
In [11]: s5 = pd.Series(a, ['a', 'b', 'c'])
In [12]: print(s5)
a 7
b 7
c 7
dtype: int64

В созданной структуре Series имеется три элемента с одинаковым содержанием.

Работа с элементами Series

В будущем будет написан отдельный урок, посвященный индексации и работе с элементами Series и DataFrame, сейчас рассмотрим основные подходы.

К элементам Series можно обращаться по численному индексу, при таком подходе работа со структурой не отличается от работы со списками в Python.

In [13]: s6 = pd.Series([1, 2, 3, 4, 5], ['a', 'b', 'c', 'd', 'e'])
In [14]: s6[2]
Out[14]: 3

Можно использовать метку, тогда работа с Series будет похожа на работу со словарем (dict) в Python.

In [15]: s6['d']
Out[15]: 4

Доступно получение slice’ов.

In [16]: s6[:2]
Out[16]:
a 1
b 2
dtype: int64

В поле для индекса можно поместить условное выражение.

In [17]: s6[s6 <= 3]
Out[17]:
a 1
b 2
c 3
dtype: int64

Со структурами Series можно работать как с векторами: складывать, умножать вектор на число и т.п.

In [18]: s7 = pd.Series([10, 20, 30, 40, 50], ['a', 'b', 'c', 'd', 'e'])
In [19]: s6 + s7
Out[19]:
a 11
b 22
c 33
d 44
e 55
dtype: int64

In [20]: s6 * 3
Out[20]:
a 3
b 6
c 9
d 12
e 15
dtype: int64

Структура данных DataFrame

Если Series представляет собой одномерную структуру, которую для себя можно представить как таблицу с одной строкой, то DataFrame – это уже двумерная структура – полноценная таблица с множеством строк и столбцов.

Перед работой с DataFrame не забудьте импортировать библиотеку pandas.

Конструктор класса DataFrame выглядит так:

class pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)

data – массив ndarray, словарь (dict) или другой DataFrame;

index – список меток для записей (имена строк таблицы);

columns – список меток для полей (имена столбцов таблицы);

dtype – объект numpy.dtype, определяющий тип данных;

copy – создает копию массива данных, если параметр равен True в ином случае ничего не делает.

Структуру DataFrame можно создать на базе:

  • словаря (dict) в качестве элементов которого должны выступать: одномерные ndarray, списки, другие словари, структуры Series;
  • двумерные ndarray;
  • структуры Series;
  • структурированные ndarray;
  • другие DataFrame.

Рассмотрим на практике различные подходы к созданию DataFrame’ов.

Создание DataFrame из словаря

В данном случае будет использоваться одномерный словарь, элементами которого будут списки, структуры Series и т.д.

Начнем с Series.

In [3]: d = {"price":pd.Series([1, 2, 3], index=['v1', 'v2', 'v3']),
   ...: "count": pd.Series([10, 12, 7], index=['v1', 'v2', 'v3'])}
In [4]: df1 = pd.DataFrame(d)

In [5]: print(df1)
   count price
v1    10     1
v2    12     2
v3     7     3

In [6]: print(df1.index)
Index(['v1', 'v2', 'v3'], dtype='object')

In [7]: print(df1.columns)
Index(['count', 'price'], dtype='object')

Теперь построим аналогичный словарь, но на элементах ndarray.

In [8]: d2 = {"price":np.array([1, 2, 3]),
   ...: "count": np.array([10, 12, 7])}
In [9]: df2 = pd.DataFrame(d2, index=['v1', 'v2', 'v3'])
In [10]: print(df2)
   count price
v1    10     1
v2    12     2
v3     7     3

In [11]: print(df2.index)
Index(['v1', 'v2', 'v3'], dtype='object')

In [12]: print(df2.columns)
Index(['count', 'price'], dtype='object')

Как видно – результат аналогичен предыдущему. Вместо ndarray можно использовать обычный список из Python.

Создание DataFrame из списка словарей

До это мы создавали DataFrame из словаря, элементами которого были структуры Series, списки и массивы, сейчас мы создадим DataFrame из списка, элементами которого являются словари.

In [13]: d3 = [{"price": 3, "count":8}, {"price": 4, "count": 11}]
In [14]: df3 = pd.DataFrame(d3)
In [15]: print(df3)
  count price
0     8     3
1    11     4

In [16]: print(df3.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 2 columns):
count 2 non-null int64
price 2 non-null int64
dtypes: int64(2)
memory usage: 112.0 bytes
None

Создание DataFrame из двумерного массива

Создать DataFrame можно также и из двумерного массива, в нашем примере это будет ndarray из библиотеки numpy.

In [17]: nda1 = np.array([[1, 2, 3], [10, 20, 30]])
In [18]: df4 = pd.DataFrame(nda1)
In [19]: print(df4)
   0  1  2
0  1  2  3
1 10 20 30

Работа с элементами DataFrame

Работа с элементами DataFrame – доступ к элементам данной структуры – тема достаточно обширная и она будет освещена в одном из ближайших уроков. Сейчас мы рассмотрим наиболее часто используемые способы работы с элементами DataFrame.

Основные подходы представлены в таблице ниже.

Операция Синтаксис Возвращаемый результат
Выбор столбца df[col] Series
Выбор строки по метке df.loc[label] Series
Выбор строки по индексу df.iloc[loc] Series
Слайс по строкам df[0:4] DataFrame
Выбор строк, отвечающих условию df[bool_vec] DataFrame

Теперь посмотрим, как использовать данные операций на практике.

Для начала создадим DataFrame.

In [3]: d = {"price":np.array([1, 2, 3]),
   ...: "count": np.array([10, 20, 30])}
In [4]: df = pd.DataFrame(d, index=['a', 'b', 'c'])
In [5]: print(df)
  count price
a    10     1
b    20     2
c    30     3

Операция: выбор столбца.

In [6]: df['count']
Out[6]:
a 10
b 20
c 30
Name: count, dtype: int32

Операция: выбор строки по метке.

In [7]: df.loc['a']
Out[7]:
count 10
price 1
Name: a, dtype: int32

Операция: выбор строки по индексу.

In [8]: df.iloc[1]
Out[8]:
count 20
price 2
Name: b, dtype: int32

Операция: slice по строкам.

In [9]: df[0:2]
Out[9]:
  count price
a    10     1
b    20     2

Операция: выбор строк, отвечающих условию.

In [10]: df[df['count'] >= 20]
Out[10]:
  count price
b    20     2
c    30     3 

P.S.

Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.

Книга: Pandas. Работа с данными

<<<Урок 3. Доступ к данным в структурах pandas     Урок 1. Введение в pandas и его установка>>>

Изучаем pandas. Урок 2. Структуры данных Series и DataFrame: 6 комментариев

  1. Lumen

    Опечатка: случае[т]
    В большинстве случает, при создании Series

    P.S. Спасибо за статью!

  2. Vijit

    > Конструктор класса Series выглядит следующим образом:
    > … fastpath=False

    Про этот параметр ничего не сказали.

  3. Vijit

    И слово “slice”, которое вы как только не склоняете здесь и далее в книге, переводится как “срез”. Это вполне себе русское и подходящее по смыслу слово.

    1. writer

      Как мне кажется, ‘slice’ стало уже сленговым словом, и его вполне можно употреблять. Но слово ‘срез’ звучит тоже не плохо))) В данном случае выбор был сделан в пользу первого.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *