pandas指南-2.数据索引,选择与赋
目录
索引,选择与赋值
选择要处理的pandas DataFrame或Series的特定值几乎是你将研究的任何数据操作中的隐式步骤。 因此,对如何切分数据集的充分理解至关重要。
在这个案例里,我们将查看澳大利亚墨尔本的房价数据。
点击这里 下载 数据集
我们将使用read_csv函数将数据读入DataFrame。 这样做:
import pandas as pd
melbourne_data = pd.read_csv('melb_data.csv')
pd.set_option("display.max_rows", 5)
原生的访问方法
原生Python对象提供了许多索引数据的好方法。 pandas将所有这些都包含在内,这有助于让它更容易入手。
考虑一下这个DataFrame:
melbourne_data
在Python中,我们可以通过将其作为属性访问来访问对象的属性。 例如,book对象可能有title属性,我们可以通过调用book.title来访问它。 pandas DataFrame中的列以相同的方式工作。
因此,要访问房价数据的地址属性,我们可以使用:
melbourne_data.Address
如果我们在Python中有一个dict对象,我们可以使用索引([])运算符访问它的值。 同样,我们可以对pandas DataFrame列执行相同的操作。
melbourne_data['Address']
这是从pandas DataFrame中选择特定Series的两种方法。 它们中的任何一个都没有或多或少比另外一个在语法上有效,但索引operator []确实具有可以处理其中包含保留字符的列名的优点(例如,如果我们有一个country providence列,则由于有空格review.country providence就无法工作了)。
pandas Series看起来不像是一个花哨的字典吗? 它几乎是,所以毫不奇怪,要深入到单个特定值,我们只需要再次使用索引运算符[]:
melbourne_data['Address'][0]
'85 Turner St'
基于索引来选择数据
索引操作符和属性选择很好,因为它们的工作方式与Python生态系统的其他部分一样。 作为一个新手,这使他们易于使用。 但是,pandas有自己的访问器运算符loc和iloc。 对于更高级的操作,这些是你应该使用的操作。
pandas索引在两种范例之一中起作用。 第一种是基于索引的选择:根据数据中的数字位置选择数据。 iloc遵循这种范式。
要选择此DataFrame中的第一行数据,我们可能会使用以下内容:
melbourne_data.iloc[0]
loc和iloc都是行优先,列其次。 这与我们在原生Python中所做的相反,原生Python是列优先,行其次。
这意味着检索行更容易,并且获取检索列的难度稍大。 要使用iloc获取某列时候,我们可以执行以下操作:
melbourne_data.iloc[:, 0]
:运算符,也来自原生Python,意思是“所有的”。 但是,当与其他选择器结合使用时,它可用于指示一系列值。 例如,要选择第一行,第二行和第三行房屋所在的郊县列,我们会执行以下操作:
melbourne_data.iloc[:3, 0]
或者,要仅选择第二行和第三行条目,我们会这样做:
melbourne_data.iloc[1:3, 0]
也可以传递一个列表:
melbourne_data.iloc[[0, 1, 2], 0]
最后,负数也可用于选择。 这将从值的结尾开始向前计数。 例如,这里是数据集的最后五个元素。
melbourne_data.iloc[-5:]
基于标签来选择数据
属性选择的第二个范例是loc运算符后面的范例:基于标签的选择。 在这个范例中,重要的是数据索引值,而不是它的位置。
例如,要获得房价数据中的第一个条目,我们现在将执行以下操作:
melbourne_data.loc[0, 'Suburb']
'Abbotsford'
iloc在概念上比loc更简单,因为它忽略了数据集的索引。 当我们使用iloc时,我们将数据集视为一个大矩阵(a list of lists),我们必须按位置索引。 相比之下,loc使用索引中的信息来完成其工作。 由于你的数据集通常具有有意义的索引,因此使用loc通常更容易。 例如,这里有一个使用loc更容易的操作:
melbourne_data.loc[:, ['Suburb', 'Address', 'Price']]
在loc和iloc之间选择或转换时,有一个值得记住的“问题”,即两种方法使用略有不同的索引方案。
iloc使用Python stdlib索引方案,其中包含范围的第一个元素,排除最后一个元素。因此0:10将选择条目0,...,9。同时,loc包含索引。因此0:10将选择条目0,...,10。
为什么要改变?请记住,loc可以索引任何stdlib类型:例如,字符串。如果我们有一个带有索引值Apples,...,Potatoes,...的DataFrame,并且我们想要选择“苹果和土豆之间的所有按首字母排序的水果”,那么使用 df.loc ['Apples':'Potatoes']比df.loc ['Apples','Potatoet]更加方便(t在字母表中的s后面)。
当DataFrame索引是简单的数字列表时,例如,这尤其令人困惑。 0,...,1000。在这种情况下,df.iloc [0:1000]将返回1000个条目,而df.loc [0:1000]将返回1001个条目!要使用loc获取1000个元素,你需要降低一个并请求df.iloc [0:999]。
操纵索引
基于标签的选择从索引中的标签获得实力。 关键的是,我们使用的索引不是一成不变的。 我们可以以我们认为合适的任何方式操纵索引。
set_index方法可用于完成工作。 以下是set_index到title字段时发生的情况:
melbourne_data.set_index("Address")
如果你可以为数据集提供比当前数据集更好的索引,则执行set_index非常有用。
条件选择
到目前为止,我们一直使用DataFrame本身的结构属性索引各种数据。 但是,为了对数据做有趣的事情,我们经常需要根据条件提出问题。
例如,假设我们特别关注区县为Abbotsford的房屋。
我们可以先询问每个房屋是否为Abbotsford:
melbourne_data.Suburb == 'Abbotsford'
此操作根据每条记录的区县Suburb生成一系列真/假布尔值。 然后可以在loc内部使用此结果来选择相关数据:
melbourne_data.loc[melbourne_data.Suburb == 'Abbotsford']
这个DataFrame有大约56行。 原来有~13580。 这意味着大约0.4%的房屋来自Abbotsford。
我们也想知道房价高于一定数额的房屋有多少
我们可以使用&符号(&)将两个问题放在一起:
melbourne_data.loc[(melbourne_data.Suburb == 'Abbotsford') & (melbourne_data.Price >= 1000000)]
pandas附带了一些预先构建的条件选择器,其中两个我们将在这里重点介绍。
第一个是isin。 isin是允许你选择值“在”值的列表中的数据。 例如,以下是我们如何使用它来选择仅来自Abbotsford或Airport West的房屋:
melbourne_data.loc[melbourne_data.Suburb.isin(['Abbotsford', 'Airport West'])]
第二个是isnull(和它的伴侣notnull)。 这些方法可以突出显示非空(NaN)的值。 例如,要过滤掉数据集中缺少价格标签的房屋,我们将采取以下措施:
melbourne_data.loc[melbourne_data.Price.notnull()]
赋值操作
另一方面,将数据赋值给DataFrame很容易。 你可以指定一个常量值:
melbourne_data['critic'] = 'everyone'
melbourne_data['critic']
0 everyone 1 everyone ... 13578 everyone 13579 everyone Name: critic, Length: 13580, dtype: object
或者使用可迭代的值:
melbourne_data['index_backwards'] = range(len(melbourne_data), 0, -1)
melbourne_data['index_backwards']
0 13580 1 13579 ... 13578 2 13579 1 Name: index_backwards, Length: 13580, dtype: int64
推荐阅读