文章目录

  • Pandas数据取值与选择
  • 1.Series对象数据选取方法
  • 将Series对象看做字典
  • 取值
  • 添加值
  • 检索值和键
  • 将Sereies对象看做一维数组
  • 将显式索引作为切片
  • 将隐式数字作为切片
  • 掩码操作
  • 花哨的索引
  • 索引器:loc,iloc和ix
  • loc索引器
  • iloc索引器
  • ix索引器
  • 2.DataFrame对象数据选取方法
  • 将DataFrame看做字典
  • 取值
  • 添加值
  • 将DataFrame看做二维数组
  • 查询值
  • 转置
  • 获取值
  • 使用索引器
  • iloc索引器
  • loc索引器


Pandas数据取值与选择

作为数据分析这一系列的内容,在学习Pandas之前应该已经学习了Numpy(参考Numpy学习专栏)

其中讲解了获取,设置,调整Numpy数组数值的方法和工具,包括通过偏移量来取值,通过切片操作来取值,掩码操作,花哨的索引,组合索引等等.

其实Pandas中数据的取值与选择和Numpy非常相似,但是有几个小细节需要注意一下.

由于Series对象具有两种视角:具有显式索引的一维数组和有序字典.因此Series对象的取值也就相应有两种方式

DataFrame对象也具有两种视角:具有显式行列索引的二维数组和由列索引映射到Series对象的字典,因DataFrame对象的取值方式也有两种.

下面就将来一一介绍


1.Series对象数据选取方法

就像前面所说的,Series对象可以视为一维数组或者字典,因此我们需要牢牢记住这两个类比.这样有助于我们更好的理解Series对象数据选取的方法

将Series对象看做字典

取值

与Python中原生的字典一样,使用键名来获取

Series对象名[键名]

例如:

Series_1=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
print(Series_1)
print(Series_1['a'])
>>>
a    1
b    2
c    3
d    4
e    5
dtype: int64
1
添加值

类似于字典,我们可以指定新的键值对来为Series对象添加值

Series对象名[新键名]=新键值

例如:

Series_1=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
print(Series_1)
Series_1['e']=6
print(Series_1)
>>>
a    1
b    2
c    3
d    4
e    5
dtype: int64
a    1
b    2
c    3
d    4
e    6
dtype: int64
检索值和键

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

查询某个键名是否在Series对象中

键名 in Series对象名

查询Series对象所有的键名

Series对象名.keys()

查询Series对象所有的键值对

Series对象名.item()

例如:

print('a' in Series_1)
print('f' in Series_1)
print(Series_1.keys())
print(Series_1.item())
>>>
a    1
b    2
c    3
d    4
e    5
dtype: int64
True
False
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
<zip object at 0x0CE12940>

将Sereies对象看做一维数组

Series对象不仅具有和字典一样的接口以便于Python中的原生字典操作能对Series对象起作用,还具有Numpy的ndarray对象一样的数据选择功能,包括索引,掩码,花哨的索引等操作.

将显式索引作为切片
Series对象名[起始显式索引:终止显式索引:步长]

需要注意的是:通过显示索引切片的操作最后一个值如果在步长范围内将会取到

例如:

Series_1=pd.Series([0.25,0.5,0.75,1.0],index=['a','b','c','d'])
print(Series_1['a':'c'])
print(Series_1['a':'c':2])
>>>
a    0.25
b    0.50
c    0.75
dtype: float64
a    0.25
c    0.75
dtype: float64
将隐式数字作为切片
Series对象名[起始偏移量:终止偏移量:步长]

需要注意的是:通过隐式数组作为索引进行的切片操作最后一个值无论是否在步长范围内都不会被取到

例如:

Series_1=pd.Series([0.25,0.5,0.75,1.0],index=['a','b','c','d'])
print(Series_1[0:2])
print(Series_1[0:2:2])
>>>
a    0.25
b    0.50
dtype: float64
a    0.25
dtype: float64
掩码操作

直接举例

Series_1=pd.Series([0.25,0.5,0.75,1.0],index=['a','b','c','d'])
print(Series_1)
print(Series_1[Series_1>0.4])	
>>>
a    0.25
b    0.50
c    0.75
d    1.00
dtype: float64
b    0.50
c    0.75
d    1.00
dtype: float64
花哨的索引

直接举例

Series_1=pd.Series([0.25,0.5,0.75,1.0],index=['a','b','c','d'])
print(Series_1[['a','d']])
>>>
a    0.25
d    1.00
dtype: float64

索引器:loc,iloc和ix

通过上面的讲解,我们不难发现,当使用显式索引进行切片操作的时候,会包含最后一个值,而使用隐式索引的时候,不会包含最后一个值.

这样的差异这就造成了麻烦,如果我们的显式索引也是数字呢?那么可想而知会带来极大地不便.

因此,正是因为整数索引很容易造成混淆,Pandas中提供了一些索引器(indexer)属性来作为取值的方法

这些indexer并不是Series对象的方法,而是暴露切片接口的属性.

具体的索引器有三个,分别是:loc,iloc和ix

下面将来讲解

loc索引器

使用loc索引器,则取值和切片都是显式的

Series对象名.loc[索引]
Series对象名.loc[起始偏移量:终止偏移量:步长]

例如:

Series_1=pd.Series([0.25,0.5,0.75,1.0])
print(Series_1)
print(Series_1[0])
print(Series_1.loc[0])
print(Series_1[0:3])
print(Series_1.loc[0:3])
>>>
0    0.25
1    0.50
2    0.75
3    1.00
dtype: float64
0.25
0.25
0    0.25
1    0.50
2    0.75
dtype: float64
0    0.25
1    0.50
2    0.75
3    1.00
dtype: float64
iloc索引器

使用iloc索引器,表示切片和索引默认都是隐式的

Series对象名.iloc[索引]
Series对象名.iloc[起始偏移量:终止偏移量:步长]

例如:

Series_1=pd.Series([0.25,0.5,0.75,1.0])
print(Series_1)
print(Series_1[0])
print(Series_1.iloc[0])
print(Series_1[0:3])
print(Series_1.iloc[0:3])
>>>
0    0.25
1    0.50
2    0.75
3    1.00
dtype: float64
0.25
0.25
0    0.25
1    0.50
2    0.75
dtype: float64
0    0.25
1    0.50
2    0.75
dtype: float64
ix索引器

使用ix索引器表示显式和隐式索引的混合,主要用于DataFrame对象中.新版Pandas已经删除


2.DataFrame对象数据选取方法

前面说过,DataFrame对象可以看具有行列索引的二维数组,或者是共享索引的若干个Series对象构成的字典.牢记这两个类比会帮助我们更好的掌握数据结构的数据选择方法

将DataFrame看做字典

取值

可以使用键名(即列索引)来获得某一列的所有值

注意,此时只能通过列索引来获取一列的值,如果使用行索引就会报错

DataFrame对象名[列索引]

例如:

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
print(DataFrame_1['col_1'])
>>>
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
row_1    0
row_2    4
row_3    8
Name: col_1, dtype: int32

我们还可以使用属性来选择纯字符串列名的数据

DataFrame对象名.列索引

例如:

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
# print(DataFrame_1['col_1'])
print(DataFrame_1.col_1)
>>>
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
row_1    0
row_2    4
row_3    8
Name: col_1, dtype: int32

但是需要注意,此时列索引必须是字符串形式,否则会报错

col=[1,'col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
print(DataFrame_1.1)
>>>
       1  col_2  col_3  col_4
row_1  0      1      2      3
row_2  4      5      6      7
row_3  8      9     10     11
 File "路径", line 139
    print(DataFrame_1.1)
                      ^
SyntaxError: invalid syntax

而且如果列名与DataFrame对象的方法同名,那么调用的时候就会使用对应的方法而非索取值

添加值

和Series对象一样,我们把DataFrame对象看作是字典的话,可以指定新的键值对来增加新的列

DataFrame对象名[新的列索引]=Series对象名

例如:

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
DataFrame_1['col_5']=DataFrame_1['col_1']/DataFrame_1['col_2']
print(DataFrame_1)
>>>
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
       col_1  col_2  col_3  col_4     col_5
row_1      0      1      2      3  0.000000
row_2      4      5      6      7  0.800000
row_3      8      9     10     11  0.888889

将DataFrame看做二维数组

查询值

我们可以使用values属性来查询DataFrame对象的所有值

DataFrame对象名.values

例如:

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
print(DataFrame_1.values)
>>>
      col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
转置

我们可以使用Numpy的ndarray对象的转置方法,来对DataFrame对象进行转置

DataFrame对象名.T

例如:

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
print(DataFrame_1.T)
>>>
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
       row_1  row_2  row_3
col_1      0      4      8
col_2      1      5      9
col_3      2      6     10
col_4      3      7     11

注意,转置之后可以对新的DataFrame对象的列(即原先的行)来进行索引,从而达到索引行的效果

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
print(DataFrame_1.T)
print(DataFrame_1.T.row_1)
>>>
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
       row_1  row_2  row_3
col_1      0      4      8
col_2      1      5      9
col_3      2      6     10
col_4      3      7     11
col_1    0
col_2    1
col_3    2
col_4    3
Name: row_1, dtype: int64
获取值

我们将DataFrame看做字典,就可以通过键名(Series对象名)来获取这样一列的所有值.

为了获取行,我们可以将DataFrame对象转置之后获取列.

但是如果我们将DataFrame对象视为Numpy的二维数组,我们可以直接通过行索引来获取某一行数据

也可以使用切片操作来获取某一行或者某一列的数据

DataFrame对象名.values[行索引]
DataFrame对象名.values[行切片,列切片]

例如:

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1.values)
print(DataFrame_1.values[0])
print(DataFrame_1.values[0,:])
print(DataFrame_1.values[:,0])
>>>
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[0 1 2 3]
[0 1 2 3]
[0 4 8]
使用索引器

前面我们再Series对象的取值中讲解了三个索引器,这三种索引器在DataFrame对象的取值上会发挥更大的作用

iloc索引器

我们可以使用iloc索引器来索引DataFrame对象底层的Numpy数组,即索引隐式索引

DataFrame对象名.iloc[行索引]
DataFrame对象名.iloc[行切片,列切片]

例如:

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
print(DataFrame_1.iloc[:,:])
print(DataFrame_1.iloc[0])
print(DataFrame_1.iloc[0,:])
print(DataFrame_1.iloc[:,0])
>>>
    col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
col_1    0
col_2    1
col_3    2
col_4    3
Name: row_1, dtype: int64
col_1    0
col_2    1
col_3    2
col_4    3
Name: row_1, dtype: int64
row_1    0
row_2    4
row_3    8
Name: col_1, dtype: int64
loc索引器

我们可以使用loc索引器来索引显示索引

DataFrame对象名.loc[列索引名]
DataFrame对象名.loc[行切片,列切片]

例如

col=['col_1','col_2','col_3','col_4']
row=['row_1','row_2','row_3']
DataFrame_1=pd.DataFrame(np.arange(12).reshape((3,4)),columns=col,index=row)
print(DataFrame_1)
print(DataFrame_1['col_1'])
print(DataFrame_1.loc['row_1':'row_2','col_1':'col_4'])
>>>
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7
row_3      8      9     10     11
row_1    0
row_2    4
row_3    8
Name: col_1, dtype: int64
       col_1  col_2  col_3  col_4
row_1      0      1      2      3
row_2      4      5      6      7