

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 |