Добавил:
Developer Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / 10. Датафреймы pandas - Jupyter Notebook

.pdf
Скачиваний:
44
Добавлен:
15.12.2022
Размер:
2.39 Mб
Скачать
def _has_valid_setitem_indexer(self, indexer):

12.11.2022, 11:38 10. Датафреймы pandas - Jupyter Notebook

In [26]:

df.iloc[:, 'Mstat': 'Econ']

---------------------------------------------------------------------------

TypeError Traceback (most recent call last) <ipython-input-26-25ef00bcf778> in <module>()

----> 1 df.iloc[:, 'Mstat': 'Econ']

/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in __getitem_

_(self, key)

except (KeyError, IndexError):

1470

1471

pass

-> 1472

return self._getitem_tuple(key)

1473

else:

1474

# we by definition only have the 0th axis

/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in _getitem_t uple(self, tup)

2027

continue

2028

 

-> 2029

retval = getattr(retval, self.name)._getitem_axis(key, a

xis=axis)

 

2030

# if the dim was reduced, then pass a lower-dim the next

2031

time

 

/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in _getitem_a xis(self, key, axis)

2078

if

isinstance(key,

slice):

2079

-> 2080

 

return self._get_slice_axis(key, axis=axis)

2081

if

isinstance(key,

list):

2082

/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in _get_slice _axis(self, slice_obj, axis)

2046

return obj.copy(deep=False)

2047

 

-> 2048

slice_obj = self._convert_slice_indexer(slice_obj, axis)

2049

if isinstance(slice_obj, slice):

2050

return self._slice(slice_obj, axis=axis, kind='iloc')

/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in _convert_s lice_indexer(self, key, axis)

264# if we are accessing via lowered dim, use the last dim

265ax = self.obj._get_axis(min(axis, self.ndim - 1))

--> 266 return ax._convert_slice_indexer(key, kind=self.name)

267

268

/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py in _conve rt_slice_indexer(self, key, kind)

1688

# validate iloc

1689

if kind == 'iloc':

-> 1690

return slice(self._validate_indexer('slice', key.start,

kind),

self._validate_indexer('slice', key.stop, k

1691

ind),

self._validate_indexer('slice', key.step, k

1692

ind))

 

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

21/42

12.11.2022, 11:38 10. Датафреймы pandas - Jupyter Notebook

/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py in _valid ate_indexer(self, form, key, kind)

4126

pass

4127

elif kind in ['iloc', 'getitem']:

-> 4128

self._invalid_indexer(form, key)

4129

return key

4130

 

/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py in _inval id_indexer(self, form, key)

1846

"indexers [{key}] of {kind}".format(

1847

form=form, klass=type(self), key=key,

-> 1848

kind=type(key)))

1849

def get_duplicates(self):

1850

TypeError: cannot do slice indexing on <class 'pandas.core.indexes.base.Inde x'> with these indexers [Mstat] of <class 'str'>

Python пишет, что невозможно взять срез по индексам, которые имеют строковый тип ( class 'str' ), так как в квадратных скобках ожидаются числовые (целочисленные) индексы.

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

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

22/42

12.11.2022, 11:38

10. Датафреймы pandas - Jupyter Notebook

In [27]:

df.iloc[:, 1:3]

Out[27]:

 

Mstat

Soc

id

 

 

 

 

 

М141БПЛТЛ024

9

8

М141БПЛТЛ031

10

10

М141БПЛТЛ075

9

9

М141БПЛТЛ017

9

8

М141БПЛТЛ069

10

10

М141БПЛТЛ072

9

8

М141БПЛТЛ020

7

7

М141БПЛТЛ026

10

8

М141БПЛТЛ073

9

8

М141БПЛТЛ078

6

9

М141БПЛТЛ060

8

7

М141БПЛТЛ040

9

8

М141БПЛТЛ065

9

8

М141БПЛТЛ053

7

7

М141БПЛТЛ015

9

7

М141БПЛТЛ021

9

8

М141БПЛТЛ018

7

9

М141БПЛТЛ039

8

9

М141БПЛТЛ036

10

7

М141БПЛТЛ049

7

6

06114043

8

10

М141БПЛТЛ048

6

8

М141БПЛТЛ034

9

7

М141БПЛТЛ045

8

8

М141БПЛТЛ033

9

8

М141БПЛТЛ083

5

6

М141БПЛТЛ008

8

8

М141БПЛТЛ001

7

7

М141БПЛТЛ038

9

6

М141БПЛТЛ052

7

7

М141БПЛТЛ011

6

8

М141БПЛТЛ004

7

6

М141БПЛТЛ010

6

7

М141БПЛТЛ071

9

7

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

23/42

12.11.2022, 11:38

 

 

10. Датафреймы pandas - Jupyter Notebook

 

 

Mstat

Soc

 

id

 

 

 

 

 

 

 

 

 

М141БПЛТЛ035

6

7

 

 

М141БПЛТЛ030

6

6

 

 

М141БПЛТЛ070

5

6

 

 

М141БПЛТЛ051

9

8

 

 

М141БПЛТЛ046

7

7

 

 

М141БПЛТЛ047

8

6

 

 

М141БПЛТЛ063

5

6

 

 

М141БПЛТЛ029

8

8

 

 

М141БПЛТЛ064

8

6

 

 

М141БПЛТЛ076

7

8

 

 

М141БПЛТЛ062

7

7

 

 

М141БПЛТЛ074

6

7

 

130232038

7

6

 

 

М141БПЛТЛ023

9

6

 

 

М141БПЛТЛ054

8

6

 

 

М141БПЛТЛ012

6

7

 

 

М141БПЛТЛ006

5

6

 

 

М141БПЛТЛ055

5

6

 

 

М141БПЛТЛ007

7

7

 

 

М141БПЛТЛ050

6

6

 

 

М141БПЛТЛ066

10

7

 

 

М141БПЛТЛ043

5

6

 

 

М141БПЛТЛ084

7

8

 

 

М141БПЛТЛ005

7

5

 

 

М141БПЛТЛ044

5

7

 

13051038

4

4

 

Числовые срезы в pandas уже ничем не отличаются от списковых срезов: правый конец среза не включается. В нашем случае мы выбрали только столбцы с индексами 1 и 2.

Выбор строк по названию

Выбор строки по названию происходит аналогичным образом, только здесь метод .loc уже обязателен.

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

24/42

12.11.2022, 11:38

10. Датафреймы pandas - Jupyter Notebook

In [28]:

df.loc['М141БПЛТЛ031'] # строка для студента с номером М141БПЛТЛ031

Out[28]:

 

Cps

8.0

Mstat

10.0

Soc

10.0

Econ

10.0

Eng

10.0

Polth

10.0

Mstat2

10.0

Phist

9.0

Law

9.0

Phil

10.0

Polsoc

10.0

Ptheo

9.0

Preg

8.0

Compp

8.0

Game

9.0

Wpol

10.0

Male

1.0

Name: М141БПЛТЛ031, dtype: float64

При этом ставить запятую и двоеточие, показывая, что нам нужна одна строка и все столбцы, уже не нужно. Если нам нужно выбрать несколько строк подряд, то .loc не нужен:

In [29]:

df["М141БПЛТЛ024":'М141БПЛТЛ069']

Out[29]:

 

 

 

Cps

Mstat

Soc

Econ

Eng

Polth

Mstat2

Phist

Law

Phil

Polsoc

Ptheo

 

 

id

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

М141БПЛТЛ024

7

9

8

8

9

8

10

8.0

7

9

9

7.0

 

М141БПЛТЛ031

8

10

10

10

10

10

10

9.0

9

10

10

9.0

 

М141БПЛТЛ075

9

9

9

10

9

10

9

8.0

9

10

9

9.0

 

М141БПЛТЛ017

9

9

8

8

9

9

10

6.0

9

9

9

8.0

 

М141БПЛТЛ069

10

10

10

10

10

10

9

8.0

8

10

9

7.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Как Python понимает, что мы просим вывести именно строки с такими названиями, а не столбцы? Потому что у нас стоят одинарные квадратные скобки, а не двойные, как в случае со столбцами. (Да, в pandas много всяких тонкостей, но чтобы хорошо в них разбираться, нужно просто попрактиковаться и привыкнуть).

Обратите внимание: разницы между двойными и одинарными кавычками нет, строки можно вводить в

любых кавычках, как в примере выше.

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

В этом случае достаточно указать номер в квадратных скобках в .iloc :

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

25/42

12.11.2022, 11:38

10. Датафреймы pandas - Jupyter Notebook

In [30]:

df.iloc[2]

Out[30]:

 

Cps

9.0

Mstat

9.0

Soc

9.0

Econ

10.0

Eng

9.0

Polth

10.0

Mstat2

9.0

Phist

8.0

Law

9.0

Phil

10.0

Polsoc

9.0

Ptheo

9.0

Preg

8.0

Compp

8.0

Game

7.0

Wpol

9.0

Male

1.0

Name: М141БПЛТЛ075, dtype: float64

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

In [31]:

df[1:3] # и без iloc

Out[31]:

 

 

 

Cps

Mstat

Soc

Econ

Eng

Polth

Mstat2

Phist

Law

Phil

Polsoc

Ptheo

 

 

id

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

М141БПЛТЛ031

8

10

10

10

10

10

10

9.0

9

10

10

9.0

 

М141БПЛТЛ075

9

9

9

10

9

10

9

8.0

9

10

9

9.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Если нужно несколько строк не подряд, можно просто перечислить внутри списка в .iloc :

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

26/42

12.11.2022, 11:38

10. Датафреймы pandas - Jupyter Notebook

In [32]:

df.iloc[[1, 2, 5, 10]]

Out[32]:

 

 

 

Cps

Mstat

Soc

Econ

Eng

Polth

Mstat2

Phist

Law

Phil

Polsoc

Ptheo

 

 

id

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

М141БПЛТЛ031

8

10

10

10

10

10

10

9.0

9

10

10

9.0

 

М141БПЛТЛ075

9

9

9

10

9

10

9

8.0

9

10

9

9.0

 

М141БПЛТЛ072

10

9

8

10

9

8

9

8.0

8

10

9

7.0

 

М141БПЛТЛ060

7

8

7

7

9

8

8

5.0

7

5

8

5.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Выбор наблюдений по названиям строк и столбцов

Если нам нужно выбрать одно наблюдение на пересечении строки и столбца, можно воспользоваться методом .at : сначала указать название строки, потом ‒ столбца:

In [33]:

df.at['М141БПЛТЛ078', 'Game'] # оценка по теории игр у студента М141БПЛТЛ078

Out[33]:

6

Кроме того, можно применить метод .loc :

In [34]:

df.loc["М141БПЛТЛ075", "Soc"] # оценка по социологии у студента М141БПЛТЛ075

Out[34]:

9

В чем разница между .at и .loc ? Метод .loc более универсален. В то время как .at используется для нахождения одного наблюдения на пересечении строки и столбца, .loc позволяет выбрать несколько наблюдений (строк и столбцов) сразу. Например, так:

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

27/42

12.11.2022, 11:38

10. Датафреймы pandas - Jupyter Notebook

In [35]:

df.loc["М141БПЛТЛ024":"М141БПЛТЛ073", "Mstat"]

Out[35]:

id

М141БПЛТЛ024 9 М141БПЛТЛ031 10 М141БПЛТЛ075 9 М141БПЛТЛ017 9 М141БПЛТЛ069 10 М141БПЛТЛ072 9 М141БПЛТЛ020 7 М141БПЛТЛ026 10 М141БПЛТЛ073 9

Name: Mstat, dtype: int64

Если нужно выбрать какое-то одно значение, метод .at будет работать более быстро, чем .loc .

*Выбор наблюдения по номеру строки и столбца *

Выбор наблюдения по номеру строки и столбца осуществляется аналогичным образом, только теперь мы используем методы с префиксом i для индексов: .iat и .iloc .

In [36]:

df.iat[4, 6] # оценка на пересечении строки 4 и столбца 6

Out[36]:

9

In [37]:

df.iloc[8, 4] # оценка на пересечении строки 8 и столбца 4

Out[37]:

9

Убедимся, что все верно:

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

28/42

12.11.2022, 11:38 10. Датафреймы pandas - Jupyter Notebook

In [38]: df.head(8) Out[38]:

 

 

 

Cps

Mstat

Soc

Econ

Eng

Polth

Mstat2

Phist

Law

Phil

Polsoc

Ptheo

 

 

id

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

М141БПЛТЛ024

7

9

8

8

9

8

10

8.0

7

9

9

7.0

 

М141БПЛТЛ031

8

10

10

10

10

10

10

9.0

9

10

10

9.0

 

М141БПЛТЛ075

9

9

9

10

9

10

9

8.0

9

10

9

9.0

 

М141БПЛТЛ017

9

9

8

8

9

9

10

6.0

9

9

9

8.0

 

М141БПЛТЛ069

10

10

10

10

10

10

9

8.0

8

10

9

7.0

 

М141БПЛТЛ072

10

9

8

10

9

8

9

8.0

8

10

9

7.0

 

М141БПЛТЛ020

8

7

7

6

9

10

8

8.0

7

7

9

7.0

 

М141БПЛТЛ026

7

10

8

7

10

7

9

8.0

8

8

8

8.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Выбор строк по условию (фильтрация наблюдений)

Часто в исследованиях нас не интересует выбор отдельных строк по названию или номеру, мы хотим отбирать строки в таблице согласно некорому условию (условиям). Другими словами, проводить фильтрацию наблюдений. Для этого интересующее нас условие необходимо указать в квадратных скобках. Выберем из датафрейма df строки, которые соответствуют студентам с оценкой по экономике выше 6.

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

29/42

12.11.2022, 11:38

10. Датафреймы pandas - Jupyter Notebook

In [39]:

df[df["Econ"] > 6]

Out[39]:

 

 

 

Cps

Mstat

Soc

Econ

Eng

Polth

Mstat2

Phist

Law

Phil

Polsoc

Ptheo

 

 

id

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

М141БПЛТЛ024

7

9

8

8

9

8

10

8.0

7

9

9

7.0

 

М141БПЛТЛ031

8

10

10

10

10

10

10

9.0

9

10

10

9.0

 

М141БПЛТЛ075

9

9

9

10

9

10

9

8.0

9

10

9

9.0

 

М141БПЛТЛ017

9

9

8

8

9

9

10

6.0

9

9

9

8.0

 

М141БПЛТЛ069

10

10

10

10

10

10

9

8.0

8

10

9

7.0

 

М141БПЛТЛ072

10

9

8

10

9

8

9

8.0

8

10

9

7.0

 

М141БПЛТЛ026

7

10

8

7

10

7

9

8.0

8

8

8

8.0

 

М141БПЛТЛ073

7

9

8

8

9

8

9

8.0

8

9

9

7.0

 

М141БПЛТЛ060

7

8

7

7

9

8

8

5.0

7

5

8

5.0

 

М141БПЛТЛ021

8

9

8

8

9

8

8

7.0

7

7

6

6.0

 

М141БПЛТЛ018

7

7

9

7

9

7

8

6.0

6

7

8

7.0

 

М141БПЛТЛ039

9

8

9

8

8

8

6

8.0

7

6

9

6.0

 

М141БПЛТЛ036

8

10

7

8

8

6

9

4.0

8

8

7

6.0

 

М141БПЛТЛ045

5

8

8

7

8

6

7

6.0

7

7

8

6.0

 

М141БПЛТЛ033

5

9

8

7

9

7

9

7.0

7

8

8

7.0

 

М141БПЛТЛ008

10

8

8

9

8

10

9

8.0

9

10

9

8.0

 

М141БПЛТЛ052

7

7

7

7

8

6

6

6.0

8

6

7

5.0

 

М141БПЛТЛ071

6

9

7

7

9

6

8

4.0

6

7

7

6.0

 

М141БПЛТЛ029

6

8

8

7

9

5

6

7.0

6

5

8

5.0

 

М141БПЛТЛ064

7

8

6

7

6

6

8

4.0

6

4

4

4.0

 

М141БПЛТЛ023

7

9

6

8

9

6

9

4.0

7

7

7

6.0

 

М141БПЛТЛ066

7

10

7

7

9

5

8

4.0

6

5

6

4.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Почему нельзя было написать проще, то есть df["Econ"] > 6 ? Давайте напишем, и посмотрим, что получится:

127.0.0.1:8888/notebooks/EXONTOOLS/2/Доп. занятия/10. Датафреймы pandas.ipynb

30/42