Python: Pandas

Теория: Работа с индексами

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

Структура объекта DataFrame

Рассмотрим объект DataFrame. Он состоит из набора столбцов, каждый из которых является объектом Series:

import pandas as pd

df_orders = pd.read_excel('./data/Orders.xlsx')
print(df_orders.head())
# => shop_1	shop_2	shop_3	shop4
# 0	  7.0	  1	     7.0	  8
# 1	  4.0	  2	     4.0	  5
# 2	  3.0	  5	     NaN	  3
# 3	  8.0	 12	     8.0	  7
# 4	 15.0    11	    13.0      9

Применим функцию type() к столбцу df_orders:

print(type(df_orders['shop_1']))
# => pandas.core.series.Series

Объект Series спроектирован, чтобы хранить одномерные структуры данных. Он состоит из двух связанных между собой массивов: меток и значений:

print(df_orders.shop_1)
# => 0     7.0
#    1     4.0
#    2     3.0
#    3     8.0
#    4    15.0
#    5    21.0
#    6     NaN
#    Name: shop_1, dtype: float64

Выбрать несколько столбцов можно следующим образом:

print(df_orders[['shop_1','shop_2']].head())
# => shop_1	shop_2
#  0   7.0	  1
#  1   4.0	  2
#  2   3.0	  5
#  3   8.0	 12
#  4  15.0	 11
#

При выборе нескольких столбцов мы будем снова получать тип данных DataFrame.

Иногда легче выбросить несколько столбцов, чем перечислять необходимые. В этом случае нужно использовать метод drop():

print(df_orders.drop(['shop_4'], axis=1).head())
# => shop_1	shop_2	shop_3
# 0	  7.0	  1	     7.0
# 1	  4.0	  2  	 4.0
# 2	  3.0	  5      NaN
# 3	  8.0	 12	     8.0
# 4	 15.0	 11	    13.0

В методе drop() нужно задавать значение параметра axis. Значение 0 будет указывать, что нужно исключить некоторые строки. Значение 1 указывает на исключение столбцов.

Метод drop() возвращает новый объект DataFrame и оставляет без изменений исходный.

Индексы объектов DataFrame и Series

У каждой строки объекта DataFrame или значения у Series есть индекс. Индекс может быть как числом, так и строкой. Список индексов объектов DataFrame и Series можно получить с помощью атрибута index:

print(df_orders.index)
# RangeIndex(start=0, stop=7, step=1)
print(df_orders.shop_1.index)
# RangeIndex(start=0, stop=7, step=1)

Если нужно, можно изменить значение индексов и имя столбца с индексами:

df_orders.index = range(0,16,2)
df_orders.index.name = 'New indexes'
print(df_orders.head())
# =>          shop_1	shop_2	shop_3	shop4
# New indexes
#          0	7.0	      1	     7.0	  8
#          2	4.0	      2	     4.0	  5
#          4	3.0	      5	     NaN	  3
#          6	8.0	     12	     8.0	  7
#          8	15.0	 11	    13.0	  9

Строковые индексы обычно называют метки или ключи:

df_orders.index = ['a','b','c','d','e','f','g']
print(df_orders.head())
# => shop_1	shop_2	shop_3	shop_4
# a	   7.0	  1	     7.0	  8
# b	   4.0	  2	     4.0	  5
# c	   3.0	  5	     NaN	  3
# d	   8.0	 12	     8.0	  7
# e	  15.0	 11	    13.0	  9

Методы получения значений по индексу

Разберем следующие методы:

  • loc() — метод выбора данных на основе меток строк
  • iloc() — метод выбора строк согласно их числовой позиции

loc()

Выберем одну строку из объекта DataFrame по ее метке:

print(df_orders.loc['b'])
# => shop_1    4.0
#    shop_2    2.0
#    shop_3    4.0
#    shop_4    5.0
# Name: b, dtype: float64

Выберем несколько строк:

print(df_orders.loc[['b','c']])
# => shop_1	shop_2	shop_3	shop_4
# b	  4.0	  2	     4.0	  5
# c	  3.0	  5	     NaN	  3

iloc()

Выберем одну строку:

print(df_orders.iloc[1])
# => shop_1    4.0
#    shop_2    2.0
#    shop_3    4.0
#    shop_4    5.0
# Name: b, dtype: float64

Выберем несколько строк:

print(df_orders.iloc[[1,2]])
# => shop_1	shop_2	shop_3	shop_4
# b	  4.0	  2	     4.0	  5
# c	  3.0	  5	     NaN	  3

Фильтрация строк и столбцов одновременно

Методы loc() и iloc() позволяют выполнять фильтрацию по строкам и столбцам одновременно. Пример для loc():

print(df_orders.loc[['b','c'],['shop_2','shop_4']])
# => shop_2	shop_4
#  b	2	5
#  c	5	3

Пример для iloc():

print(df_orders.iloc[[2,4],[1,3]])
# => shop_2	shop4
#  c	5	3
#  e	11	9

Как и при использовании методов отдельно для строк и столбцов, метод loc() ожидает на вход метки, а iloc() — номера позиций строк и столбцов.

Срезы

Срезы позволяют получать совокупности строк в определенном диапазоне. Пример:

print(df_orders.loc['b':'d'])
# =>  shop_1	shop_2	shop_3	shop_4
#  b	4.0	      2	      4.0	  5
#  c	3.0	      5	      NaN	  3
#  d	8.0	     12	      8.0	  7

В срез данных попали все строки между позициями 1 и 3 включительно. Позиции 1 и 3 соответствуют меткам 'b' и 'd'. Можно строить более интересные срезы:

print(df_orders.loc['b':'f':2])
# => shop_1	shop_2	shop_3	shop_4
# b	   4.0	  2	     4.0	  5
# d	   8.0	 12 	 8.0      7
# f	  21.0	 18	    17.0	 21

В данный срез попала каждая вторая строка между строками с метками 'b' и 'f'.

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

print(df_orders.loc['b':'f':2, 'shop_1':'shop_3'])
# => shop_1	shop_2	shop_3
# b	  4.0	  2	     4.0
# d	  8.0	 12	     8.0
# f	 21.0	 18	    17.0

В срез попала каждая вторая строка между строками с метками 'b' и 'f' и столбцы с метками от 'shop_1' до 'shop_3' включительно.

Аналогично получаются срезы с помощью метода iloc(). Приведем пример, который совпадает по результату с примером выше:

print(df_orders.iloc[1:6:2, 0:3])
# b	  4.0	  2	     4.0
# d	  8.0	 12	     8.0
# f	 21.0	 18	    17.0

Выводы

Работа с данными может производиться над конкретными элементами, строками, столбцами или их комбинациями. В этом уроке мы познакомились с фильтрацией значений таблиц по индексам строк и столбцов объекта DataFrame библиотеки Pandas. Изложенные методы позволяют получать различные срезы данных в соответствии с условиями на индексы.

Рекомендуемые программы