100天搞定机器学习(100-Days-Of-ML)(十五)Pandas数据取值与选择

第十五天

Pandas数据取值与选择

在前面介绍了获取、设置、调整Numpy数组数值的方法,包括取值操作、切片操作、掩码操作、花哨的索引以及组合操作。下面介绍Pandas的Series 和DataFrame 对象相似的数据获取与调整操作。

一、Series数据选择

如前所述,Series 对象与一维NumPy 数组和标准Python 字典在许多方面都一样。只要牢记住这两个类比,就可以帮助我们更好地理解Series 对象的数据索引与选择模式.

1.将Series看作字典

和字典一样,Series对象提供了键值对的映射:

import pandas as pd
data = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a', 'b', 'c', 'd'])
data
# a 0.25
  b 0.50
  c 0.75
  d 1.00
  dtype: float64
  
data['b']
# 0.5

我们还可以用Python字典的表达式和方法来检测键/索引和值:

'a' in data
# True
data.keys()
# Index(['a', 'b', 'c', 'd'], dtype='object')
list(data.items())
# [('a', 0.25), ('b', 0.5), ('c', 0.75), ('d', 1.0)]

Series 对象还可以用字典语法调整数据。就像你可以通过增加新的键扩展字典一样,你也可以通过增加新的索引值扩展Series:

data['e'] = 1.25
data
# a 0.25
  b 0.50
  c 0.75
  d 1.00
  e 1.25
  dtype: float64

Series 对象的可变性是一个非常方便的特性:Pandas 在底层已经为可能发生的内存布局和数据复制自动决策,用户不需要担心这些问题。

2.将Series看作一维数组

Series 不仅有着和字典一样的接口,而且还具备和NumPy 数组一样的数组数据选择功能,包括索引、掩码、花哨的索引等操作,具体示例如下所示:

# 将显式索引作为切片
data['a':'c']
# a 0.25
  b 0.50
  c 0.75
  dtype: float64
# 将隐式整数索引作为切片
data[0:2]
# a 0.25
  b 0.50
  dtype: float64

在以上示例中, 切片是绝大部分混乱之源。需要注意的是, 当使用显式索引( 即data[‘a’:‘c’])作切片时,结果包含最后一个索引;而当使用隐式索引(即data[0:2])作切片时,结果不包含最后一个索引。

3.索引器:loc、iloc和ix

这些切片和取值的习惯用法经常会造成混乱。例如,如果你的Series 是显式整数索引,那么data[1] 这样的取值操作会使用显式索引,而data[1:3] 这样的切片操作却会使用隐式索引。

data = pd.Series(['a', 'b', 'c'], index=[1, 3, 5])
data
#
1 a
3 b
5 c
dtype: object
# 取值操作是显式索引
data[1]
# 'a'
# 切片操作是隐式索引
data[1:3]
# 3 b
  5 c
  dtype: object

由于整数索引很容易造成混淆,所以Pandas 提供了一些索引器(indexer)属性来作为取值的方法。它们不是Series 对象的函数方法,而是暴露切片接口的属性。

第一种索引器是loc 属性,表示取值和切片都是显式的:

data.loc[1]
# 'a'
data.loc[1:3]
# 1 a
  3 b
  dtype: object

第二种是iloc 属性,表示取值和切片都是Python 形式的隐式索引:

data.iloc[1]
# 'b'
data.iloc[1:3]
# 3 b
  5 c
  dtype: object

第三种取值属性是ix,它是前两种索引器的混合形式,在Series 对象中ix 等价于标准的[](Python 列表)取值方式。ix 索引器主要用于DataFrame 对象,后面将会介绍。

二、DataFrame数据选择

DataFrame 在有些方面像二维或结构化数组,在有些方面又像一个共享索引的若干Series 对象构成的字典。这两种类比可以帮助我们更好地掌握这种数据结构的数据选择方法。

1.将DataFrame看作字典

第一种类比是把DataFrame 当作一个由若干Series 对象构成的字典。

area = pd.Series({'California': 423967, 'Texas': 695662,
'New York': 141297, 'Florida': 170312,
'Illinois': 149995})
pop = pd.Series({'California': 38332521, 'Texas': 26448193,
'New York': 19651127, 'Florida': 19552860,
'Illinois': 12882135})
data = pd.DataFrame({'area':area, 'pop':pop})
data

#
             area pop
California 423967 38332521
Florida 170312 19552860
Illinois 149995 12882135
New York 141297 19651127
Texas 695662 26448193

两个Series 分别构成DataFrame 的一列,可以通过对列名进行字典形式(dictionary-style)的取值获取数据:

data['area']
#
California 423967
Florida 170312
Illinois 149995
New York 141297
Texas 695662
Name: area, dtype: int64

同样,也可以用属性形式(attribute-style)选择纯字符串列名的数据:

data.area
#
California 423967
Florida 170312
Illinois 149995
New York 141297
Texas 695662
Name: area, dtype: int64


虽然属性形式的数据选择方法很方便,但是它并不是通用的。如果列名不是纯字符串,或者列名与DataFrame 的方法同名,那么就不能用属性索引。

还可以用字典形式的语法调整对象,例如要增加一列数据可以这样做:

data['density'] = data['pop'] / data['area']
#
               area pop density
California 423967 38332521 90.413926
Florida 170312 19552860 114.806121
Illinois 149995 12882135 85.883763
New York 141297 19651127 139.076746
Texas 695662 26448193 38.018740

2.将DataFrame看作二维数组

可以把DataFrame 看成是一个增强版的二维数组,用values 属性按行查看数组数据:

data.values
#
array([[ 4.23967000e+05, 3.83325210e+07, 9.04139261e+01],
       [ 1.70312000e+05, 1.95528600e+07, 1.14806121e+02],
       [ 1.49995000e+05, 1.28821350e+07, 8.58837628e+01],
       [ 1.41297000e+05, 1.96511270e+07, 1.39076746e+02],
       [ 6.95662000e+05, 2.64481930e+07, 3.80187404e+01]])

理解了这一点,就可以把许多数组操作方式用在DataFrame 上,例如可以对DataFrame对象进行转置:

data.T
#
         California  Florida    Illinois     New York     Texas
area 4.239670e+05 1.703120e+05 1.499950e+05 1.412970e+05 6.956620e+05
pop 3.833252e+07 1.955286e+07 1.288214e+07 1.965113e+07 2.644819e+07
density 9.041393e+01 1.148061e+02 8.588376e+01 1.390767e+02 3.801874e+01

通过字典形式对列进行取值显然会限制我们把DataFrame 作为NumPy 数组可以获得的能力,尤其是当我们在DataFrame 数组中使用单个行索引获取一行数据时:

data.values[0]
#
array([ 4.23967000e+05, 3.83325210e+07, 9.04139261e+01])

而获取一列数据就需要向DataFrame对象传递单个列索引:

data['area'] # 如前面展示

因此,在进行数组形式的取值时,我们就需要用另一种方法——前面介绍过的Pandas 索引器loc、iloc 和ix 了。通过iloc 索引器,我们就可以像对待NumPy 数组一样索引Pandas的底层数组(Python 的隐式索引),DataFrame 的行列标签会自动保留在结果中:

data.iloc[:3, :2] #隐式索引 取的是前三行和后两列数据
data.loc[:'Illinois', :'pop'] #显示索引 取的是前三行和后两列数据

使用ix索引器可以实现一种混合效果:

data.ix[:3, :'pop'] #取的是前三行和后两列数据

值得注意的是,任何用于处理NumPy 形式数据的方法都可以用于这些索引器。例如,可以在loc 索引器中结合使用掩码与花哨的索引方法:

data.loc[data.density > 100, ['pop', 'density']]

任何一种取值方法都可以用于调整数据,这一点和NumPy 的常用方法是相同的:

data.iloc[0, 2] = 90

3.其他取值方法

还有一些其他取值方法,如对单个标签取值、切片、掩码操作等。

data['Florida':'Illinois'] # 使用单个标签
data[1:3] # 切片使用行数
data[data.density > 100] # 掩码操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值