Pandas---3.下标存取([]/loc/iloc/ix/at/iat/query方法/多级索引/整数label)
一、[ ] 操作符
1.Index
对于Index
对象,可以通过[]
来选取数据,它类似于一维ndarray
的索引。下标可以为下列几种下标对象:
-
一个整数下标。此时返回对应的
label
-
一个整数
slice
。此时返回对应的Index
(根据一维labels
先切片,再组装成Index
) -
一个
array-like
对象(元素可以为下标或者布尔值)。此时返回对应的Index
。(根据一维labels
先索引,再组装成Index
) -
由
None
组成的二元组,其中None
相当于新建一个轴。- 如果
None
为第一个元素,则新建的轴为 0 轴; - 如果
None
为第二个元素,则新建的轴为 1 轴。 - 另外
idx[None]
等价于idx[None,:]
,但是idx[None]
返回的是ndarray
。 - 它并没有将
Index
转换成MultiIndex
,只是将Index
内部的数据数组扩充了一个轴
- 如果
Index 的索引只支持整数/整数
slice
/整数序列/布尔序列/整数数组/布尔数组/None 等。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) idx # Index(['a', 'b', 'c', 'd'], dtype='object', name='idx1') idx[ 0 ],idx[ 0 : 2 ] # 整数或者切片 # ('a', Index(['a', 'b'], dtype='object', name='idx1')) idx[ None ],idx[ 0 , None ],idx[:, None ],idx[ None ,:] # 扩充为二维数组 # (array([['a', 'b', 'c', 'd']], dtype=object), Index([ 'a' ], dtype = 'object' , name = 'idx1' ), Index([[ 'a' ], [ 'b' ], [ 'c' ], [ 'd' ]], dtype = 'object' , name = 'idx1' ), Index([[ 'a' , 'b' , 'c' , 'd' ]], dtype = 'object' , name = 'idx1' )) idx[[ 0 , 1 , 2 , 3 ]],idx[np.array([ 1 , 2 , 3 ])],idx[[ True , True , False , False ]] # 一维序列 # (Index(['a', 'b', 'c', 'd'], dtype='object', name='idx1'), Index([ 'b' , 'c' , 'd' ], dtype = 'object' , name = 'idx1' ), Index([ 'a' , 'b' ], dtype = 'object' , name = 'idx1' )) idx[np.array([[ 0 , 1 ],[ 1 , 2 ]])] # 二维数组 # Index([['a', 'b'], ['b', 'c']], dtype='object', name='idx1') |
2.Series
(1)[]
对于Series
对象,可以通过[]
来选取数据,它类似于一维ndarray
的索引。下标可以为下列几种下标对象:
-
一个整数下标/一个属性(属性名为某个
label
)/字典索引(键为label
):返回对应的数值 -
一个整数切片/一个
label
切片:返回对应的Series
。(根据一维Series
先切片,再组装成Series
)。注意:label
切片同时包含了起始label
和终止label
-
一个整数
array-like
/一个label array-like
/一个布尔ndarray
:返回对应的Series
。(根据一维Series
先索引,再组装成Series
) - 一个二维整数
array-like
/二维label array-like
:返回对应值组成的二维ndarray
注意:
Series
必须使用布尔数组来索引,不支持布尔序列来索引(抛出KeyError
异常)。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | idx # Index(['a', 'b', 'c', 'd'], dtype='object', name='idx1') s = pd.Series([ 0 , 3 , 5 , 7 ],index = idx,name = 'ser1' ) s # idx1 a 0 b 3 c 5 d 7 Name: ser1, dtype: int64 s.a,s[ 'b' ],s[ 2 ] # 单个label,单个loc # (0, 3, 5) print (s[ 'a' : 'c' ],s[ 0 : 2 ],sep = '\n------\n' ) # 切片labels,切片loc # idx1 a 0 b 3 c 5 Name: ser1, dtype: int64 - - - - - - idx1 a 0 b 3 Name: ser1, dtype: int64 print (s[[ 'a' , 'c' , 'b' ]],s[[ 3 , 0 , 1 ]],sep = '\n------\n' ) # 序列label,序列loc # idx1 a 0 c 5 b 3 Name: ser1, dtype: int64 - - - - - - idx1 d 7 a 0 b 3 Name: ser1, dtype: int64 r1 = s[np.array([ 'a' , 'c' , 'b' ])] r2 = s[np.array([ 0 , 1 , 1 , 3 ])] r3 = s[np.array([[ 0 , 1 ],[ 1 , 3 ]])] print (r1, type (r1),r2, type (r2),r3, type (r3),sep = "\n----------\n" ) # 数组label,数组loc # idx1 a 0 c 5 b 3 Name: ser1, dtype: int64 - - - - - - - - - - < class 'pandas.core.series.Series' > - - - - - - - - - - idx1 a 0 b 3 b 3 d 7 Name: ser1, dtype: int64 - - - - - - - - - - < class 'pandas.core.series.Series' > - - - - - - - - - - [[ 0 3 ] [ 3 7 ]] - - - - - - - - - - < class 'numpy.ndarray' > r = s[s> 4 ] print (r) # 数组label,数组loc # idx1 c 5 d 7 Name: ser1, dtype: int64 |
(2)索引标签
Series
对象除了支持使用位置作为下标存取元素之外,还可以使用索引标签来存取元素。这个功能与字典类似,因此它也支持字典的一些方法,如Series.iteritems()
。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | bool_df = pd.DataFrame({ 'c1' :[ True , False ], 'c4' :[ True , False ]},index = [ 'a' , 'e' ]) df[bool_df] # 一个布尔DataFrame,未出现的值为False # c1 c2 c3 idx1 a 1.0 NaN NaN b NaN NaN NaN c NaN NaN NaN d NaN NaN NaN idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'index1' ) s = pd.Series([ 1 , 3 , 5 , 7 ],index = idx,name = 'sr1' ) s # index1 a 1 b 3 c 5 d 7 Name: sr1, dtype: int64 s.iteritems() # <zip at 0x21ba1c8e288> [item for item in s.iteritems()] # [('a', 1), ('b', 3), ('c', 5), ('d', 7)] |
(3)对于Series
的赋值与删除
- 对于单个索引或者切片索引,要求右侧数值的长度与左侧相等
- 为不存在的
label
赋值会创建出一个新行(必须用字典的形式,不能用属性赋值的形式) - 关键字
del
用于删除行(必须用字典的形式,不能用属性赋值的形式)
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | s = pd.Series(np.arange( 1 , 4 ),index = [ 'a' , 'b' , 'c' ]) s # a 1 b 2 c 3 dtype: int32 s.a = - 1 # 直接赋值 s # a -1 b 2 c 3 dtype: int32 s[ 0 : 2 ] = - 11 , - 22 # 元组赋值 s # a -11 b - 22 c 3 dtype: int32 s[ 'd' ] = 4 # 创建一个新的行 s # a -11 b - 22 c 3 d 4 dtype: int64 del s[ 'd' ] s # a - 11 b - 22 c 3 dtype: int64 |
3.DataFrame
(1)[]
对于DataFrame
对象,可以通过[]
来选取数据。下标可以为下列几种下标对象:
-
一个属性(属性名为某个
column label
)/字典索引(键为column label
):返回对应的列对应的Series
不可以使用单个整数来索引
-
一个整数切片/一个
row label
切片:返回对应的行组成的DataFrame
。注意:label
切片同时包含了起始label
和终止label
-
一个一维
label array-like:
返回对应的列组成的DataFrame
-
一个布尔数组:返回数组中
True
对应的行组成的DataFrame
。 -
一个布尔
DataFrame
:将该布尔DataFrame
中的False
对应的元素设置为NaN
(布尔DataFrame
中没有出现的值为False
)
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 print (df.c1,df[ 'c2' ],sep = '\n------------\n' ) # 单个值,选取列 # idx1 a 1 b 2 c 3 d 4 Name: c1, dtype: int64 - - - - - - - - - - - - idx1 a 5 b 6 c 7 d 8 Name: c2, dtype: int64 print (df[ 0 : 2 ],df[ 'a' : 'c' ],sep = '\n------------\n' ) # 切片,选取行 # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 - - - - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 print (df[[ 'c1' , 'c2' , 'c1' ]],df[np.array([ 'c1' , 'c2' , 'c3' ])],sep = '\n------------\n' ) #序列,选取列 # c1 c2 c1 idx1 a 1 5 1 b 2 6 2 c 3 7 3 d 4 8 4 - - - - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 df[df.c1> = 3 ] # 一维布尔数组 # c1 c2 c3 idx1 c 3 7 11 d 4 8 12 bool_df = pd.DataFrame({ 'c1' :[ True , False ], 'c4' :[ True , False ]},index = [ 'a' , 'e' ]) df[bool_df] # 一个布尔DataFrame,未出现的值为False # c1 c2 c3 idx1 a 1.0 NaN NaN b NaN NaN NaN c NaN NaN NaN d NaN NaN NaN |
(2)对于DataFrame
的赋值与列删除
- 将列表或者数组赋值给某个列时,其长度必须跟
DataFrame
的行数匹配。 - 将标量赋值给某个列时,会将标量扩充
- 将
Series
赋值给某个列时,会精确匹配DataFrame
的索引。如果DataFrame
中某个label
在Series
中找不到,则赋值NaN
(空位都将被填上缺失值) - 为不存在的列赋值会创建出一个新列(必须用字典的形式,不能用属性赋值的形式)
- 关键字
del
用于删除列(必须用字典的形式,不能用属性赋值的形式)
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import numpy as np import pandas as pd df = pd.DataFrame(np.arange( 0 , 12 ).reshape( 3 , 4 ),index = [ 'a' , 'b' , 'c' ],columns = [ 'c1' , 'c2' , 'c3' , 'c4' ]) df # c1 c2 c3 c4 a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 df.c1 = [ - 1 , - 4 , - 8 ] # 长度匹配 df # c1 c2 c3 c4 a - 1 1 2 3 b - 4 5 6 7 c - 8 9 10 11 df.c2 = - 2 # 可以赋值一个标量,标量扩充 df #c1 c2 c3 c4 a - 1 - 2 2 3 b - 4 - 2 6 7 c - 8 - 2 10 11 df.c3 = pd.Series( range ( 10 , 14 ),index = [ 'a' , 'c' , 'd' , 'e' ]) df # Series长度任意,df.cs中的label与Series中的匹配,如果无匹配则赋值NaN # c1 c2 c3 c4 a - 1 - 2 10.0 3 b - 4 - 2 NaN 7 c - 8 - 2 11.0 11 df[ 'c5' ] = [ - 1 , - 2 , - 3 ] # 创建一个新列 df # c1 c2 c3 c4 c5 a - 1 - 2 10.0 3 - 1 b - 4 - 2 NaN 7 - 2 c - 8 - 2 11.0 11 - 3 del df[ 'c5' ] df # c1 c2 c3 c4 a - 1 - 2 10.0 3 b - 4 - 2 NaN 7 c - 8 - 2 11.0 11 |
4.注意事项
(1)对于Series/DataFrame
切片方式的索引,返回的结果与原始对象共享基础数据。对于采用其他方式的索引,返回的结果并不与元素对象共享基础数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'index1' ) s = pd.Series([ 1 , 3 , 5 , 7 ],index = idx,name = 'sr1' ) s # index1 a 1 b 3 c 5 d 7 Name: sr1, dtype: int64 r = s[ 1 :] # 切片形式 print (r.values.base is s.values) r = s[[ 1 , 2 ]] # 序列/数组形式 print (r.values.base is s.values) # True False df = pd.DataFrame({ 'c1' :[ 1 , 3 , 5 , 6 ], 'c2' :[ 1 , 2 , 3 , 4 ], 'c3' :[ 1 , 2 , 5 , 9 ]},index = idx) df # c1 c2 c3 index1 a 1 1 1 b 3 2 2 c 5 3 5 d 6 4 9 r = df.c1 # 引用一列 print (r.values.base is df.values.base) r = df[ 'c1' : 'c3' ] # 切片形式 print (r.values.base is df.values.base) r = df[[ 'c1' , 'c2' ]] # 序列/数组形式 print (r.values.base is df.values.base) # True True False |
(2)如果Series/DataFrame
的索引有重复label
,则数据的选取行为将有所不同:
- 如果索引对应多个
label
,则Series
返回一个Sereis
,DataFrame
返回一个DataFrame
- 如果索引对应单个
label
,则Series
返回一个标量值,DataFrame
返回一个Series
你可以通过Index.is_unique
属性得知索引是否有重复的。
- 对于
[]
、字典索引、属性索引或者.loc/.ix
存取器,结论如上所述 - 对于
.at
存取器:如果索引对应单个label
,索引结果正常。如果索引对应多个label
,则Series
返回一个一维ndarray
;DataFrame
则抛出异常。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'a' , 'c' , 'd' ],name = 'idx1' ) s = pd.Series([ 1 , 5 , 3 , 7 ],index = idx,name = 'sr1' ) # 有重复值 s # idx1 a 1 a 5 c 3 d 7 Name: sr1, dtype: int64 print (s.c,s.a,s.index.is_unique,sep = '\n-----\n' ) # 重复的index返回Series # 3 - - - - - a 1 a 5 Name: sr1, dtype: int64 - - - - - False print (s.loc[ 'a' ],s.at[ 'a' ],s.ix[ 'a' ],sep = '\n------\n' ) # 重复的index # idx1 a 1 a 5 Name: sr1, dtype: int64 - - - - - - [ 1 5 ] - - - - - - idx1 a 1 a 5 Name: sr1, dtype: int64 idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) df = pd.DataFrame({ 'c1' :[ 1 , 3 , 2 , 4 ], 'c2' :[ 11 , 14 , 13 , 12 ]},index = idx) # df.columns = pd.Index(['c1','c1'],name='idx2') df # c1 c2 idx1 a 1 11 b 3 14 c 2 13 d 4 12 df.columns = pd.Index([ 'c1' , 'c1' ],name = 'idx2' ) df # idx2 c1 c1 idx1 a 1 11 b 3 14 c 2 13 d 4 12 df.index # Index(['a', 'b', 'c', 'd'], dtype='object', name='idx1') print (df.c1,s.index.is_unique,sep = '\n-------\n' ) # 重复的index,返回DataFrame # idx2 c1 c1 idx1 a 1 11 b 3 14 c 2 13 d 4 12 - - - - - - - False print (df.loc[:, 'c1' ],df.ix[:, 'c1' ],sep = '\n--------\n' ) # 重复的index # idx2 c1 c1 idx1 a 1 11 b 3 14 c 2 13 d 4 12 - - - - - - - - idx2 c1 c1 idx1 a 1 11 b 3 14 c 2 13 d 4 12 |
(3)对于Series/DataFrame
,它们可以使用ndarray
的接口。因此可以通过ndarray
的索引规则来索引它们。
1 2 | df = pd.DataFrame(...) df[:, 0 ] #使用了 ndarray 的索引方式 |
二、loc/iloc/ix 存取器
1.loc
(1)Series
对于Series
,.loc[]
的下标对象可以为:
- 单个
label
,此时返回对应的值 label
的array-like
、label slice
以及布尔array-like
:返回对应值组成的Series
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) s = pd.Series([ 0 , 3 , 5 , 7 ],index = idx,name = 'ser1' ) s # idx1 a 0 b 3 c 5 d 7 Name: ser1, dtype: int64 print (s.loc[ 'a' ],s.loc[ 'a' : 'c' ],s.loc[[ 'a' , 'c' ]],s.loc[[ True , True , False , False ]],sep = '\n-------------\n' ) #单个Label,切片label,label列表 # 0 - - - - - - - - - - - - - idx1 a 0 b 3 c 5 Name: ser1, dtype: int64 - - - - - - - - - - - - - idx1 a 0 c 5 Name: ser1, dtype: int64 - - - - - - - - - - - - - idx1 a 0 b 3 Name: ser1, dtype: int64 |
(2)DataFrame
对于DataFrame
,.loc[]
的下标对象是一个元组,其中两个元素分别与DataFrame
的两个轴对应。如果下标不是元组,则该下标对应的是第0轴,第一轴为默认值:
。
- 每个轴的下标都支持单个
label
、label array-like
、label slice
、布尔array-like
。 - 若获取的是某一列或者某一行,则返回的是
Series
;若返回的是多行或者多列,则返回的是DataFrame
;如果返回的是某个值,则是普通的标量。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 print (df.loc[ 'a' ],df.loc[ 'a' : 'c' ],df.loc[[ 'a' , 'c' ]],df.loc[[ True , False , True , False ]],sep = '\n---------\n' ) # 下标为元组,这里第二个元素默认为':' # 单个Label,切片label,label列表,布尔数组 # c1 1 c2 5 c3 9 Name: a, dtype: int64 - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 c 3 7 11 - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 c 3 7 11 print (df.loc[ 'a' , 'c1' ],df.loc[ 'a' : 'c' , 'c1' ],df.loc[[ 'a' , 'c' ], 'c1' : 'c2' ],df.loc[[ True , False , True , False ],[ True , False , False ]],sep = '\n---------\n' ) # 下标为元组,第一个为0轴,第二个为1轴 # 1 - - - - - - - - - idx1 a 1 b 2 c 3 Name: c1, dtype: int64 - - - - - - - - - c1 c2 idx1 a 1 5 c 3 7 - - - - - - - - - c1 idx1 a 1 c 3 |
2.iloc
.iloc[]
和.loc[]
类似,但是.iloc[]
使用整数下标,而不是使用label
。注意整数切片不包括最后一个值。
(1)Serise
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) s = pd.Series([ 0 , 3 , 5 , 7 ],index = idx,name = 'ser1' ) s # idx1 a 0 b 3 c 5 d 7 Name: ser1, dtype: int64 print (s.iloc[ 0 ],s.iloc[ 0 : 1 ],s.iloc[[ 0 , 1 , 2 ]],s.iloc[[ True , False , True , False ]],sep = '\n-----\n' ) # iloc使用整数下标而不是label # 0 - - - - - idx1 a 0 Name: ser1, dtype: int64 - - - - - idx1 a 0 b 3 c 5 Name: ser1, dtype: int64 - - - - - idx1 a 0 c 5 Name: ser1, dtype: int64 |
(2)DataFrame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 print (df.iloc[ 0 ],df.iloc[ 0 : 2 ],df.iloc[[ 0 , 2 ]],df.iloc[[ True , False , True , False ]],sep = '\n--------\n' ) # 下标为元组,这里第二个元素默认为':',# iloc使用整数下标而不是label # c1 1 c2 5 c3 9 Name: a, dtype: int64 - - - - - - - - c1 c2 c3 idx1 a 1 5 9 b 2 6 10 - - - - - - - - c1 c2 c3 idx1 a 1 5 9 c 3 7 11 - - - - - - - - c1 c2 c3 idx1 a 1 5 9 c 3 7 11 print (df.iloc[ 0 , 0 ],df.iloc[ 0 : 2 , 0 ],df.iloc[[ 0 , 2 ], 0 : 1 ],df.iloc[[ True , False , True , False ],[ True , False , False ]],sep = '\n--------\n' ) # 下标为元组,这里第二个元素默认为':', iloc使用整数下标而不是label # 1 - - - - - - - - idx1 a 1 b 2 Name: c1, dtype: int64 - - - - - - - - c1 idx1 a 1 c 3 - - - - - - - - c1 idx1 a 1 c 3 |
3.ix
.ix[]
存取器综合了.iloc/.loc
:它可以混合使用label
和位置下标。注意:如果有整数索引,则应该使用.loc/.iloc
从而避免混淆
(1)Series
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) s = pd.Series([ 0 , 3 , 5 , 7 ],index = idx,name = 'ser1' ) s # idx1 a 0 b 3 c 5 d 7 Name: ser1, dtype: int64 print (s.ix[ 0 ],s.ix[ 'a' : 'b' ],s.ix[[ 0 , 1 , 2 ]],s.ix[[ True , False , True , False ]],sep = '\n------\n' ) # ix混合使用整数下标和label # 0 - - - - - - idx1 a 0 b 3 Name: ser1, dtype: int64 - - - - - - idx1 a 0 b 3 c 5 Name: ser1, dtype: int64 - - - - - - idx1 a 0 c 5 Name: ser1, dtype: int64 |
(2)DataFrame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 print (df.ix[ 'a' ],df.ix[ 'a' : 'c' ],df.ix[[ 0 , 2 ]],df.ix[[ True , False , True , False ]],sep = '\n---------\n' ) # 下标为元组,这里第二个元素默认为'':,ix默认使用整数下标和label # c1 1 c2 5 c3 9 Name: a, dtype: int64 - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 c 3 7 11 - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 c 3 7 11 print (df.ix[ 0 , 'c1' ],df.ix[ 'a' : 'b' , 0 ],df.ix[[ 'a' , 'c' ]],df.ix[[ True , False , True , False ],[ True , False , False ]],sep = '\n---------\n' ) # 下标为元组,第一个为0周,第二个为1轴,ix混合使用整数下标和label # 1 - - - - - - - - - idx1 a 1 b 2 Name: c1, dtype: int64 - - - - - - - - - c1 c2 c3 idx1 a 1 5 9 c 3 7 11 - - - - - - - - - c1 idx1 a 1 c 3 |
4.注意
(1)Index
对象不能使用loc/iloc/ix
存取器
(2)对于.loc/.iloc/.ix
:
- 如果某轴的索引为
array-like
或者布尔array-like
,则返回的结果与原来的对象不再共享基础数据; - 如果轴的索引全部都是
slice
或者单个整数、单个label
,则返回的结果与原来的对象共享基础数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 r1 = df.ix[ 0 , 0 ] # 都是整数 r2 = df.loc[ 'a' ,:] # 一个切片 r3 = df.iloc[:, 0 ] # 一个切片 r4 = df.ix[: , :] # 两个切片 r5 = df.ix[ 0 ,[ 0 , 1 ]] # 一个列表 r6 = df.loc[: , [ 'c1' , 'c2' ]] # 一个列表 r7 = df.iloc[[ 0 , 1 ],[ 0 , 1 ]] # 两个列表 ( type (r1), # 都是整数 r2.values.base is df.values.base, # 一个切片 r3.values.base is df.values.base, # 一个切片 r4.values.base is df.values.base, # 一个切片 r5.values.base is df.values.base, # 一个切片 r6.values.base is df.values.base, # 一个切片 r7.values.base is df.values.base, # 一个切片 ) # (numpy.int64, True, True, True, False, False, False) |
三、at/iat 存取器
1..at
和.iat
分别使用label
和整数下标获取单个值。它类似于.loc/.iloc
,但是.at/.iat
的速度更快
- 每个索引只能是单个
label
或者单个整数
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) s = pd.Series([ 1 , 3 , 5 , 7 ],index = idx,name = 'ser1' ) s # idx1 a 1 b 3 c 5 d 7 Name: ser1, dtype: int64 print (s.at[ 'a' ],s.iat[ 0 ]) # at使用label获取单个值,iat使用整数获取单个值 # 1 1 idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 |
2.对于DataFrame
,.lookup(row_labels, col_labels)
类似于:.loc[row_labels, col_labels]
,但是.lookup
返回的是一维ndarray
。
- 要求
row_labels
和col_labels
长度相同。(row_labels[0],col_labels[0]
决定了结果中第一个元素的位置,...(row_labels[i],col_labels[i]
决定了结果中第i+1
个元素的位置,
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import numpy as np import pandas as pd df = pd.DataFrame(np.arange( 0 , 12 ).reshape( 3 , 4 ),index = [ 'a' , 'b' , 'c' ],columns = [ 'c1' , 'c2' , 'c3' , 'c4' ]) df # c1 c2 c3 c4 a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 df.lookup([ 'a' , 'b' ],[ 'c1' , 'c2' ]) # array([0, 5]) df.loc[[ 'a' , 'b' ],[ 'c1' , 'c2' ]] # c1 c2 a 0 1 b 4 5 |
3.DataFrame.get_value(index, col, takeable=False)
等价于.loc[index, col]
,它返回单个值。而Series.get_value(label, takeable=False)
等价于.loc[label]
,它也返回单个值
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) s = pd.Series([ 0 , 1 , 2 , 3 ],index = idx,name = 'ser1' ) s # idx1 a 0 b 1 c 2 d 3 Name: ser1, dtype: int64 s.get_value( 'a' ) # 返回单个值 # 0 idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 df.get_value( 'a' , 'c2' ) # 返回单个值 # 5 |
4..get(key[, default])
方法与字典的get()
方法的用法相同。对于DataFrame
,key
为col_label
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) s = pd.Series([ 0 , 1 , 2 , 3 ],index = idx,name = 'ser1' ) s # idx1 a 0 b 1 c 2 d 3 Name: ser1, dtype: int64 s.get( 'a' ),s.get( 'e' , - 1 ) # (0, -1) idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 df.get( 'c1' ),df.get( 'e' , - 1 ) # (idx1 a 1 b 2 c 3 d 4 Name: c1, dtype: int64, - 1 ) |
5..head([n=5])
和.tail([n=5])
返回头部/尾部n
行数据
四、query方法
1.对于DataFrame
,当需要根据一定的条件对行进行过滤时,通常可以先创建一个布尔数组,然后使用该数组获取True
对应的行。另一个方案就是采用query(expr, inplace=False, **kwargs)
方法:
expr
是个运算表达式字符串,如'label1 >3 and label2<5'
- 表达式中的变量名表示对应的列,可以使用
not/and/or
等关键字进行向量布尔运算。该方法会筛选出那些满足条件的行。 - 如果希望在表达式中使用
Python
变量,则在变量名之前使用@
inplace
是个布尔值,如果为True
,则原地修改。否则返回一份拷贝。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import numpy as np import pandas as pd idx = pd.Index([ 'a' , 'b' , 'c' , 'd' ],name = 'idx1' ) df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 r = df.query( 'c1+c2<10' ) print (r,df,sep = '\n------\n' ) # 非原地修改 # c1 c2 c3 idx1 a 1 5 9 b 2 6 10 - - - - - - c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c 3 7 11 d 4 8 12 r = df.query( 'c1+c2<10' ,inplace = True ) # 原地修改 print (r,df,sep = '\n------\n' ) # None - - - - - - c1 c2 c3 idx1 a 1 5 9 b 2 6 10 c1 = 3 df.query( 'c1==@c1' ) # 使用python变量 # c1 c2 c3 idx1 c 3 7 11 |
五、多级索引
1.对于.loc/.ix/[]
,其下标可以指定多级索引中,每级索引上的标签。
- 多级索引轴对应的下标是一个下标元组,该元组中每个元素与索引中每级索引对应
- 如果下标不是元组,则将其转换成长度为1的元组
- 如果元组的长度比索引的层数少,则在其后面补充
slice(None)
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import numpy as np import pandas as pd levels = [[ 'a' , 'b' ],[ 'c' , 'd' ]] labels = [[ 0 , 1 , 0 , 1 ],[ 0 , 0 , 1 , 1 ]] idx = pd.MultiIndex(levels = levels,labels = labels,names = [ 'lv1' , 'lv2' ]) s = pd.Series([ 1 , 2 , 3 , 4 ],index = idx,name = 'ser1' ) s # lv1 lv2 a c 1 b c 2 a d 3 b d 4 Name: ser1, dtype: int64 s.ix[( 0 , 0 )],s.loc[( 'a' , 'c' )] # 下标索引为元组 # (1, 1) df = pd.DataFrame({ 'c1' :[ 1 , 2 , 3 , 4 ], 'c2' :[ 5 , 6 , 7 , 8 ], 'c3' :[ 9 , 10 , 11 , 12 ]},index = idx) df # c1 c2 c3 lv1 lv2 a c 1 5 9 b c 2 6 10 a d 3 7 11 b d 4 8 12 print (df.loc[ 'a' ,[ 'c1' , 'c2' ]],df.loc[( 'a' , slice ( None )),[ 'c1' , 'c2' ]],sep = '\n----------\n' ) # 二者等价 # c1 c2 lv2 c 1 5 d 3 7 - - - - - - - - - - c1 c2 lv1 lv2 a c 1 5 d 3 7 df.loc[( slice ( None ), 'c' ),[ 'c1' , 'c2' ]] # 0轴的level为: # c1 c2 lv1 lv2 a c 1 5 b c 2 6 print (s[ 'a' ],s[:, 'c' ],s[ 'a' , 'c' ],sep = '\n-------------------------\n' ) #使用[]索引 # lv2 c 1 d 3 Name: ser1, dtype: int64 - - - - - - - - - - - - - - - - - - - - - - - - - lv1 a 1 b 2 Name: ser1, dtype: int64 - - - - - - - - - - - - - - - - - - - - - - - - - 1 |
六、整数 label
1.label
不一定是字符串,也有可能是整数(如RangeIndex/Int64Index
等),尤其是当label
是自动生成的时候。
当你的label
是整数时,面向整数的下标索引总是面向label
的,而不是面向position
的。因此推荐使用.loc
来基于label
索引,使用.iloc
来基于position
索引。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import numpy as np import pandas as pd s1 = pd.Series([ 11 , 12 , 15 , 17 ]) # 自动生成index s2 = pd.Series([ 21 , 22 , 25 , 27 ],index = [ 1 , 3 , 5 , 7 ]) # 整数index s3 = pd.Series([ 31 , 32 , 35 , 37 ],index = [ 'a' , 'b' , 'c' , 'd' ]) #字符串index print (s1,s2,s3,sep = '\n------------------------\n' ) 0 11 1 12 2 15 3 17 dtype: int64 - - - - - - - - - - - - - - - - - - - - - - - - 1 21 3 22 5 25 7 27 dtype: int64 - - - - - - - - - - - - - - - - - - - - - - - - a 31 b 32 c 35 d 37 dtype: int64 \n - - - - - - - - - - - - - - - - - - - - - - - - \n print (s1.index, type (s1.index), s2.index, type (s2.index), s3.index, type (s3.index),sep = '\n------------------------\n' ) RangeIndex(start = 0 , stop = 4 , step = 1 ) - - - - - - - - - - - - - - - - - - - - - - - - < class 'pandas.core.indexes.range.RangeIndex' > - - - - - - - - - - - - - - - - - - - - - - - - Int64Index([ 1 , 3 , 5 , 7 ], dtype = 'int64' ) - - - - - - - - - - - - - - - - - - - - - - - - < class 'pandas.core.indexes.numeric.Int64Index' > - - - - - - - - - - - - - - - - - - - - - - - - Index([ 'a' , 'b' , 'c' , 'd' ], dtype = 'object' ) - - - - - - - - - - - - - - - - - - - - - - - - < class 'pandas.core.indexes.base.Index' > # 面向position print (s2[ 7 ], # 面向label s3[ 0 ]) # 面向position 27 31 #面向position print (s2.loc[ 7 ], #面向label s2.iloc[ - 1 ], #面向position s3.loc[ 'd' ], #面向label s3.iloc[ - 1 ] #面向position ) 27 27 37 37 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
2018-12-27 去掉python的警告