如何使用Python Pandas通过索引标签选择数据的子集?
介绍
Pandas具有双重选择功能,可使用索引位置或索引标签选择数据子集。在本文中,我将展示如何使用索引标签“选择数据子集”。
记住,Python字典和列表是内置数据结构,它们通过使用索引标签或通过索引位置选择其数据。字典的键必须是字符串、整数或元组,而列表必须使用整数(位置)或切片对象进行选择。
Pandas具有.loc和.iloc属性,可以以其独特的方式执行索引操作。使用.iloc属性时,pandas仅按位置进行选择,并且与Python列表类似。.loc属性仅按索引标签选择,这类似于Python字典的工作方式。
更多Pandas文章,请阅读:Pandas教程
使用.loc[]通过索引标签选择数据子集
loc和iloc属性在Series和DataFrame上都可用。
1. 导入电影数据集,使用标题作为索引。
import pandas as pd
movies = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv",
index_col="title",
usecols=["title","budget","vote_average","vote_count"])
我总是建议排序索引,尤其是如果索引由字符串组成。如果您的索引已排序,则在处理大型数据集时,您会注意到差异。
movies.sort_index(inplace=True)
movies.head(3)
budget vote_average vote_count
title
___________________________________
#Horror 1500000 3.3 52
(500) Days of Summer 7500000 7.2 2904
10 Cloverfield Lane 15000000 6.8 2468
我使用sort_index和参数”inplace = True”对索引进行了排序。
1. loc方法的语法有趣之处在于它不需要括号()而需要方括号[]。我认为(可能错误)这是因为它们希望建立一致性,即您可以在Series上使用[]提取行,在Dataframe上使用[]获取列。
# 提取“蜘蛛侠3”的数据(我不是蜘蛛侠的大粉丝)
movies.loc["Spider-Man 3"]
budget 258000000.0
vote_average 5.9
vote_count 3576.0
Name: Spider-Man 3, dtype: float64
1.使用切片提取多个值。我将提取我没有看过的电影。因为这是一个字符串标签,我们将获得我们的搜索条件的所有数据,包括“阿凡达”。
记住-如果您使用Python List,则最后一个值被排除在外,但由于我们使用字符串,它是包含在内的。
movies.loc["Alien":"Avatar"]
budget vote_average vote_count
title
Alien 11000000 7.9 4470
Alien Zone 0 4.0 3
Alien: Resurrection 70000000 5.9 1365
Aliens 18500000 7.7 3220
Aliens in the Attic 45000000 5.3 244
... ... ... ...
Australia 130000000 6.3 694
Auto Focus 7000000 6.1 56
Automata 7000000 5.6 670
Autumn in New York 65000000 5.7 135
Avatar 237000000 7.2 11800
167行×3列
6. 我可以改变选择的顺序吗?当然可以,您可以通过指定需要的标签列表以特定顺序来帮助自己。
虽然这样指定要提取的标签列表看起来很酷,但您知道如果您拼写错误会发生什么吗? Pandas会为错误拼写的标签固定缺失值(NaN)。但是,随着最新更新的推出,它会引发异常。
movies.loc[["Avengers: Age of Ultron","Avatar","When is Avengers next movie?"]]
---------------------------------------------------------------------------
KeyError
Traceback (most recent call last)
<ipython-input-6-ebe975264840> in <module>
----> 1 movies.loc[["Avengers: Age of Ultron","Avatar","When is Avengers next movie?"]]
~\anaconda3\lib\site-packages\pandas\core\indexing.py in
__getitem__
(self, key)
1766
1767 maybe_callable = com.apply_if_callable(
key,self.obj)
-> 1768
return self._getitem_axis(maybe_callable,axis = axis)
1769
1770 def_is_scalar_access(self,key:Tuple):
~\anaconda3\lib\site-packages\pandas\core\indexing.py
in
_getitem_axis
(self, key, axis)
1952 raiseValueError("Cannot index with multidimensional key")
1953
-> 1954 return self._getitem_iterable(key,
axis=axis)
1955
1956 # nested tuple slicing
~\anaconda3\lib\site-packages\pandas\core\indexing.py
in_getitem_iterable(self, key, axis)
1593 else:
1594 # A collection of keys
-> 1595 keyarr,indexer=self._get_listlike_indexer(key,axis,raise_missing=False)
1596 return self.obj._reindex_with_indexers(
1597 {axis:[keyarr,indexer]},copy=True,allow_dups=True
~\anaconda3\lib\site-packages\pandas\core\indexing.py
in
_get_listlike_indexer(self, key, axis, raise_missing)
1550 keyarr,indexer,new_indexer=ax._reindex_non_unique
(keyarr)
1551
-> 1552 self._validate_read_indexer(
1553 keyarr,indexer,o._get_axis_number
(axis),raise_missing=raise_missing
1554 )
~\anaconda3\lib\site-packages\pandas\core\indexing.py
in
_validate_read_indexer
(self, key, indexer, axis, raise_missing)
1652 # just raising
1653 ifnot(ax.is_categorical()orax.is_interval()
)
:
-> 1654 raise KeyError(
1655 "Passing list-likes to .loc or [] with any missing labels "
1656 "is no longer supported, see "
KeyError: ‘不能使用任何丢失的标签将类似列表传递给.loc或[],请参见 https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#deprecate-loc-reindex-listlike’
一种方法可以通过直接检查索引中的值来处理。
"When is Avengers next movie?" in movies.index
输出
False
如果您想忽略错误并继续进行,则可以使用以下方法。
movies.query("title in ('Avatar','When is Avengers next Movie?')")
budget vote_average vote_count
title
Avatar 237000000 7.2 11800