В рамках этого урока будет подробно раскрыт вопрос доступа к данным в структурах Series и DataFrame. Также рассмотрены вопросы использования атрибутов, добавления элементов данных в структуры, выборка с использованием условных выражений и многое другое.
- Два подхода получения доступа к данным в pandas
- Использование различных способов доступа к данным
- Использование атрибутов для доступа к данным
- Получение случайного набора из структур pandas
- Добавление элементов в структуры
- Индексация с использованием логических выражений
- Использование isin для работы с данными в pandas
Два подхода получения доступа к данным в pandas
При работе со структурами Series и DataFrame из библиотеки pandas, как правило, используют два основных способа получения значений элементов.
Первый способ основан на использовании меток, в этом случае работа ведется через метод .loc. Если вы обращаетесь к отсутствующей метке, то будет сгенерировано исключение KeyError.
Такой подход позволяет использовать:
- метки в виде отдельных символов [‘a’] или чисел [5], числа используются в качестве меток, если при создании структуры не был указан список с метками;
- список меток [‘a’, ‘b’, ‘c’];
- слайс меток [‘a’:’c’];
- массив логических переменных;
- callable функция с одним аргументом.
Второй способ основан на использовании целых чисел для доступа к данных, он предоставляется через метод .iloc. При использовании .iloc, если вы обращаетесь к несуществующему элементу, то будет сгенерировано исключение IndexError. Логика использования .iloc очень похожа на работу с .loc. При таком подходе можно использовать:
- отдельные целые числа для доступа к элементам структуры;
- массивы целых чисел [0, 1, 2];
- слайсы целых чисел [1:4];
- массивы логических переменных;
- callable функцию с одним аргументом.
В зависимости от типа используемой структуры, будет меняться форма .loc:
- для Series, она выглядит так: s.loc[indexer];
- для DataFrame так: df.loc[row_indexer, column_indexer].
Использование различных способов доступа к данным
Создадим объекты типов Series и DataFrame, которые в дальнейшем будут использованы для экспериментов. Для этого сначала импортируем необходимые библиотеки.
In [1]: import pandas as pd
Создадим структуру Series.
In [3]: s = pd.Series([10, 20, 30, 40, 50], ['a', 'b', 'c', 'd', 'e']) In [4]: s['a'] Out[4]: 10 In [5]: s Out[5]: a 10 b 20 c 30 d 40 e 50 dtype: int64
Создадим структуру DataFrame.
In [6]: d = {"price":[1, 2, 3], "count": [10, 20, 30], "percent": [24, 51, 71]} In [7]: df = pd.DataFrame(d, index=['a', 'b', 'c']) In [8]: df Out[8]: count percent price a 10 24 1 b 20 51 2 c 30 71 3
Доступ к данным структуры Series
Доступ с использованием меток
При использовании меток для доступа к данным можно применять один из следующих подходов:
- первый, когда вы записываете имя переменной типа Series и в квадратных скобках указываете метку, по которой хотите обратиться (пример: s[‘a’]);
- второй, когда после имени переменной пишите .loc и далее указываете метку в квадратных скобках (пример: s.loc[‘a’]).
Обращение по отдельной метке.
Получение элементов с меткой ‘a’:
In [9]: s['a'] Out[9]: 10
Обращение по массиву меток.
Получение элементов с метками ‘a’, ‘c’ и ‘e’:
In [10]: s[['a', 'c', 'e']] Out[10]: a 10 c 30 e 50 dtype: int64
Обращение по слайсу меток.
Получение элементов структуры с метками от ‘a’ до ‘e’:
In [11]: s['a':'e'] Out[11]: a 10 b 20 c 30 d 40 e 50 dtype: int64
Доступ с использованием целочисленных индексов
При работе с целочисленными индексами, индекс можно ставить сразу после имени переменной в квадратных скобках (пример: s[1]), или можно воспользоваться .iloc (пример: s.iloc[1]).
Обращение по отдельному индексу.
Получение элемента с индексом 1:
In [12]: s[1] Out[12]: 20
Обращение с использованием списка индексов.
Получение элементов с индексами 1, 2 и 3.
In [13]: s[[1, 2 ,3]] Out[13]: b 20 c 30 d 40 dtype: int64
Обращение по слайсу индексов.
Получение первых трех элементов структуры:
In [14]: s[:3] Out[14]: a 10 b 20 c 30 dtype: int64
Обращение через callable функцию
При таком подходе в квадратных скобках указывается не индекс или метка, а функция (как правило, это лямбда функция), которая используется для выборки элементов структуры.
Получение всех элементов, значение которых больше либо равно 30:
In [15]: s[lambda x: x>= 30] Out[15]: c 30 d 40 e 50 dtype: int64
Обращение через логическое выражение
Данный подход похож на использование callable функции: в квадратных скобках записывается логическое выражение, согласно которому будет произведен отбор.
Получение всех элементов, значение которых больше 30:
In [16]: s[s > 30] Out[16]: d 40 e 50 dtype: int64
Доступ к данным структуры DataFrame
Доступ с использованием меток
Рассмотрим различные варианты использования меток, которые могут являться как именами столбцов таблицы, так и именами строк.
Обращение к конкретному столбцу.
Получение всех элементов столбца ‘count’:
In [17]: df['count'] Out[17]: a 10 b 20 c 30 Name: count, dtype: int64
Обращение с использованием массива столбцов.
Получение элементов столбцов ‘count’ и ‘price’:
In [18]: df[['count','price']] Out[18]: count price a 10 1 b 20 2 c 30 3
Обращение по слайсу меток.
Получение элементов с метками от ‘a’ до ‘b’.
In [19]: df['a':'b'] Out[19]: count percent price a 10 24 1 b 20 51 2
Обращение через callable функцию
Подход в работе с callable функцией для DataFrame аналогичен тому, что используется для Series, только при формировании условий необходимо дополнительно указывать имя столбца.
Получение всех элементов, у которых значение в столбце ‘count’ больше 15:
In [20]: df[lambda x: x['count'] > 15] Out[20]: count percent price b 20 51 2 c 30 71 3
Обращение через логическое выражение
При формировании логического выражения необходимо указывать имена столбцов, также как и при работе с callable функциями, по которым будет производиться выборка.
Получить все элементы, у которых ‘price’ больше либо равен 2.
In [21]: df[df['price'] >= 2] Out[21]: count percent price b 20 51 2 c 30 71 3
Использование атрибутов для доступа к данным
Для доступа к данным можно использовать атрибуты структур, в качестве которых выступают метки.
Начнем со структуры Series.
Воспользуемся уже знакомой нам структурой.
In [3]: s = pd.Series([10, 20, 30, 40, 50], ['a', 'b', 'c', 'd', 'e'])
Для доступа к элементу через атрибут необходимо указать его через точку после имени переменной.
In [4]: s.a Out[4]: 10 In [5]: s.c Out[5]: 30
Т.к. структура s имеет метки ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, то для доступа к элементу с меткой ‘a’ мы может использовать синтаксис s.a.
Этот же подход можно применить для переменной типа DataFrame.
In [6]: d = {"price":[1, 2, 3], "count": [10, 20, 30], "percent": [24, 51, 71]} In [6]: df = pd.DataFrame(d, index=['a', 'b', 'c'])
Получим доступ к столбцу ‘price’.
In [7]: df.price Out[7]: a 1 b 2 c 3 Name: price, dtype: int64
Получение случайного набора из структур pandas
Библиотека pandas предоставляет возможность получить случайный набор данных из уже существующей структуры. Такой функционал предоставляет как Series так и DataFrame. У данных структур есть метод sample(), предоставляющий случайную подвыборку.
Начнем наше знакомство с этим методом на примере структуры Series.
In [3]: s = pd.Series([10, 20, 30, 40, 50], ['a', 'b', 'c', 'd', 'e'])
Для того, чтобы выбрать случайным образом элемент из Series воспользуйтесь следующим синтаксисом.
In [4]: s.sample() Out[4]: c 30 dtype: int64
Можно сделать выборку из нескольких элементов, для этого нужно передать нужное количество через параметр n.
In [5]: s.sample(n=3) Out[5]: e 50 a 10 b 20 dtype: int64
Также есть возможность указать долю от общего числа объектов в структуре, используя параметр frac.
In [6]: s.sample(frac=0.3) Out[6]: a 10 c 30 dtype: int64
Очень интересной особенностью является то, что мы можем передать вектор весов, длина которого должна быть равна количеству элементов в структуре. Сумма весов должна быть равна единице, вес, в данном случае, это вероятность появления элемента в выборке.
В нашей тестовой структуре пять элементов, сформируем вектор весов для нее и сделаем выборку из трех элементов.
In [7]: w = [0.1, 0.2, 0.5, 0.1, 0.1] In [8]: s.sample(n = 3, weights=w) Out[8]: c 30 e 50 a 10 dtype: int64
Данный функционал также доступен и для структуры DataFrame.
In [9]: d = {"price":[1, 2, 3, 5, 6], "count": [10, 20, 30, 40, 50], "percent": [24, 51, 71, 25, 42]} In [10]: df = pd.DataFrame(d) In [11]: df.sample() Out[11]: count percent price 0 10 24 1
При работе с DataFrame можно указать ось.
df.sample(axis=1) Out[12]: count 0 10 1 20 2 30 3 40 4 50
In [13]: df.sample(n=2, axis=1) Out[13]: count price 0 10 1 1 20 2 2 30 3 3 40 5 4 50 6
In [14]: df.sample(n=2) Out[14]: count percent price 4 50 42 6 3 40 25 5
Добавление элементов в структуры
Увеличение размера структуры – т.е. добавление новых, дополнительных, элементов – это довольно распространенная задача. В pandas она решается очень просто. И самый быстрый способ понять, как это делать – попробовать реализовать эту задачу на практике.
Добавление нового элемента в структуру Series.
In [3]: s = pd.Series([10, 20, 30, 40, 50], ['a', 'b', 'c', 'd', 'e']) In [4]: s Out[4]: a 10 b 20 c 30 d 40 e 50 dtype: int64 In [5]: s['f'] = 60 In [6]: s Out[6]: a 10 b 20 c 30 d 40 e 50 f 60 dtype: int64
Добавление нового элемента в структуру DataFrame.
In [3]: d = {"price":[1, 2, 3, 5, 6], "count": [10, 20, 30, 40, 50], "percent": [24, 51, 71, 25, 42]} In [4]: df Out[4]: count percent price 0 10 24 1 1 20 51 2 2 30 71 3 3 40 25 5 4 50 42 6 In [5]: df['value'] = [3, 14, 7, 91, 5] In [6]: df Out[6]: count percent price value 0 10 24 1 3 1 20 51 2 14 2 30 71 3 7 3 40 25 5 91 4 50 42 6 5
Индексация с использованием логических выражений
На практике очень часто приходится получать определенную подвыборку из существующего набора данных. Например, получить все товары, скидка на которые больше пяти процентов, или выбрать из базы информацию о сотрудниках мужского пола старше 30 лет. Это очень похоже на процесс фильтрации при работе с таблицами или получение выборки из базы данных. Похожий функционал реализован в pandas и мы уже касались этого вопроса, когда рассматривали различные подходы к индексации.
Условное выражение записывается вместо индекса в квадратных скобках при обращении к элементам структуры.
При работе с Series возможны следующие варианты использования.
In [3]: s = pd.Series([10, 20, 30, 40, 50, 10, 10], ['a', 'b', 'c', 'd', 'e', 'f', 'g']) In [4]: s[s>30] Out[4]: d 40 e 50 dtype: int64 In [5]: s[s==10] Out[5]: a 10 f 10 g 10 dtype: int64 In [6]: s[(s>=30) & (s<50)] Out[6]: c 30 d 40 dtype: int64
При работе с DataFrame необходимо указывать столбец по которому будет производиться фильтрация (выборка).
In [3]: d = {"price":[1, 2, 3, 5, 6], "count": [10, 20, 30, 40, 50], "percent": [24, 51, 71, 25, 42], ...: "cat":["A", "B", "A", "A", "C"]} In [4]: df = pd.DataFrame(d) In [5]: df Out[5]: cat count percent price 0 A 10 24 1 1 B 20 51 2 2 A 30 71 3 3 A 40 25 5 4 C 50 42 6 In [6]: df[df["price"] > 3] Out[6]: cat count percent price 3 A 40 25 5 4 C 50 42 6
В качестве логического выражения можно использовать довольно сложные конструкции с использованием map, filter, лямбда-выражений и т.п.
In [7]: fn = df["cat"].map(lambda x: x == "A") In [8]: df[fn] Out[8]: cat count percent price 0 A 10 24 1 2 A 30 71 3 3 A 40 25 5
Использование isin для работы с данными в pandas
По структурам данных pandas можно строить массивы с данными типа boolean, по которому можно проверить наличие или отсутствие того или иного элемента. Проще всего это показать на примере.
In [3]: s = pd.Series([10, 20, 30, 40, 50, 10, 10], ['a', 'b', 'c', 'd', 'e', 'f', 'g']) In [4]: s.isin([10, 20]) Out[4]: a True b True c False d False e False f True g True dtype: bool
Работа с DataFrame аналогична работе со структурой Series.
In [3]: df = pd.DataFrame({"price":[1, 2, 3, 5, 6], "count": [10, 20, 30, 40, 50], "percent": [24, 51, 71, 25, 42]}) In [4]: df.isin([1, 3, 25, 30, 10]) Out[4]: count percent price 0 True False True 1 False False False 2 True False True 3 False True False 4 False False False
P.S.
Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.
<<< Урок 2. Структуры данных Series и DataFrame Урок 4. Работа с пропусками в данных>>>
Большое спасибо за уроки!
Но не нашёл на странице кнопки навигации “Следующий урок” (может она спряталась?).
Было бы намного удобнее.
Ошибка в имени новой структуры:
Добавление нового элемента в структуру DataFrame.
In [3]: d = {“price”:[1, 2, 3, 5, 6], “count”: [10, 20, 30, 40, 50], “percent”: [24, 51, 71, 25, 42]}
In [4]: df
Отличный урок! Очень помог!
Очень доходчиво!