首先创建示例df:
1 | df = pd.DataFrame(np.arange(16).reshape(4, 4), columns=list('ABCD'), index=list('5678')) |
df:
1 2 3 4 5 | A B C D 5 0 1 2 3 6 4 5 6 7 7 8 9 10 11 8 12 13 14 15 |
注意:df的index是str类型,如果不指定index默认是0开始的int类型
分为如下几个方面进行讨论:
1)loc,行名称列名称
2)iloc,行数列数
3)ix,行名称列名称/行数列数混合
4)df[]
5) df.x,选择单列
6)Series的筛选方法
7)bool
8)reindex
最后,再补充了获取行列名称,和缺失值处理的方法
1,loc,行名称列名称
1.1,行
1 2 3 | df.loc[ '6' ] # 行名称为6的行,即第2行,即4 5 6 7 df.loc[ '5' : '7' ] # 行名称为5至7的行,即前3行,注意是前闭后闭 df.loc[[ '5' , '7' ]] # 行名称为5和7的行,前第1第3行 |
1.2,列
1 2 3 | df.loc[:, 'B' ] # 列名称为'B‘的列,即第2列,1 5 9 13 df.loc[:, 'A' : 'C' ] # 列名称为A至C的列,即前3列,注意是前闭后闭 df.loc[:, [ 'A' , 'C' ]] # 列名称为A和C的列,即第1列第3列 |
1.3,块
1 2 3 4 | df.loc[ '5' : '7' , 'A' : 'C' ] # 行名称为5至7,列名称为A~C的一块数据,即前3行前3列 df.loc[[ '5' , '7' ], [ 'A' , 'C' ]] # 行名称为5和7,列名称为A和C的一块数据 df.loc[ '5' : '7' , [ 'A' , 'C' ]] # 行名称5至7,列名称A和C的一块数据 df.loc[[ '5' , '7' ], 'A' : 'C' ] # 行名称为5和7,列名称为A~C的一块数据 |
1.4,单元格
1 2 | df.loc[ '5' , 'A' ] # 行名称为5,列名称为A的单元格数据 df.at[ '5' , 'A' ] # 同loc但速度快点 |
2,iloc,行数列数
2.1,行
1 2 3 | df.iloc[ 1 ] # 第2行,即行名称为6的行,4 5 6 7 df.iloc[ 0 : 3 ] # 前3行 df.iloc[[ 0 , 3 ]] # 第1第4行 |
2.2,列
1 2 3 | df.iloc[:, 1 ] # 第2列,即列名称为'B'的列,1 4 9 13 df.iloc[:, 0 : 3 ] # 前3列 df.iloc[:, [ 0 , 3 ]] # 第1第4列 |
2.3,块
1 2 3 4 | df.iloc[ 0 : 3 , 0 : 3 ] # 前3行,前3列的一块数据 df.iloc[[ 0 , 3 ], [ 0 , 3 ]] # 第1第4行,第1第4列的一块数据 df.iloc[ 0 : 3 , [ 0 , 3 ]] # 前3行,第1第4列的一块数据 df.iloc[[ 0 , 3 ], 0 : 3 ] # 第1第4行,前3列的一块数据 |
2.4,单元格
1 2 | df.iloc[ 1 , 1 ] # 第1行,第1列的单元格 df.iat[ 1 , 1 ] # 同iloc但速度快点 |
3,df.ix,行名称列名称/行数列数混合
3.1,行
1 2 3 4 5 6 | df.ix[ '7' ] # 单行,下同 df.ix[ 2 ] df.ix[ 1 : 3 ] # 多行,下同 df.ix[[ 1 , 3 ]] df.ix[ '5' : '7' ] df.ix[ '5' , '7' ] |
如果是行/列的名称是int类型时,只能根据行/列名称选,不能根据行数/列数选:
1 2 3 4 | df.index = range ( 1 , 5 ) df.ix[ 2 ] # 输出是行名称为2的行,根据行数选择应该是第3行 df.index = range ( 11 , 15 ) df.ix[ 2 ] # KeyError: 2 |
3.2,列
1 2 3 4 5 6 | df.ix[:, 'C' ] # 单列,下同 df.ix[:, 2 ] df.ix[:, 1 : 3 ] # 多列,下同 df.ix[:, [ 1 , 3 ]] df.ix[:, 'A' : 'C' ] df.ix[:, [ 'A' , 'C' ]] |
3.3,块(略)
多行和多列的排列组合
3.4,单元格(略)
单行和单列的排列组合
4,df[]
4.1,行
可以接收行名称或者行数,但必须是切片
1 2 3 4 | df[ 0 : 1 ] # 第1行 df[ 0 : 3 ] # 前3行 df[ '5' : '5' ] # 行名称为5的行 df[ '5' : '7' ] # 行名称为5的行至行名称为7的行 |
行数切片时,如果行索引类型为int,则会根据行数来切片,不会根据行名称切片,这点与df.ix不同,例如:
1 2 3 | df = pd.DataFrame(np.arange( 16 ).reshape( 4 , 4 ), columns = list ( 'ABCD' ), index = range ( 5 , 9 )) df[ 5 : 8 ] # Empty DataFrame df[ 0 : 3 ] # 第1至第3行 |
4.2,列
只能接收列名称,可以是单个或列表
1 2 | df[ 'A' ] # A列 df[[ 'A' , 'C' ]] # A和C列 |
4.3,块
df[]无法选择块
4.4,单元格
df[]无法选择单元格
5,df.x
6,Series的筛选方法
上述示例中,接收参数为单个标签或索引的筛选,返回的都是Series,例如:
1 2 3 4 5 6 7 8 | df.iloc[ 1 ] df.iloc[:, 2 ] df.loc[ '5' ] df.loc[:, 'B' ] df.ix[ 2 ] df.ix[:, 'C' ] df[ 'A' ] df.A |
接收参数为切片或列表的筛选,即使只有一行/一列数据,返回的都是DataFrame:
1 2 3 4 5 | df[ 0 : 1 ] df[ '5' : '5' ] df.iloc[[ 1 ]] df.loc[:, [ 'B' ]] df[[ 'A' ]] |
因此,如果想获取单行/单列数据的DataFrame,只需要将输入的单个标签或索引改为切片或列表
可以进一步在Series中筛选值,以A列的Series为例:
1 2 3 4 5 6 | >>> df[ 'A' ] 5 0 6 4 7 8 8 12 Name: A, dtype: int32 |
筛选出Series中第二个值4的方法有:
1 2 3 4 5 6 | df[ 'A' ].iloc[ 1 ] df[ 'A' ].loc[ '6' ] df[ 'A' ].ix[ 1 ] df[ 'A' ].ix[ '6' ] df[ 'A' ][ 1 ] df[ 'A' ].values[ 1 ] |
7,bool
7.1,bool列表
上述示例中,DataFrame或者Series可以接受切片/列表参数的地方,都可以接受bool列表,保留bool列表中真值对应的项目,例如:
生成bool列表:
1 2 | chooses = [ True , False , True , False ] chooses = [i = = 0 or i = = 8 for i in df[ 'A' ]] # 结果是[True, False, True, False] |
根据bool列表筛选:
1 2 3 4 5 | df.iloc[chooses] # 只留第1第3行 df.loc[:, chooses] # 只留第1第3列 df.ix[chooses] # 只留第1第3行 df[chooses] # 只留第1第3行 df[ 'A' ][chooses] # 只留A列中第1第3个值 |
7.2,bool Series
可以根据bool Series筛选,保留bool Series真值对应的项目,但是index要与df相同
1)按列生成的Series,index是原df的index,可以对行方向操作进行筛选
生成列方向的bool Series:
1 2 3 4 5 6 7 8 9 | chooses = pd.Series([ True , False , True , False ], index = df.index) chooses = df.loc[:, 'A' ] > 1 chooses = df.iloc[:, 0 ] > 1 chooses = df[ 'A' ] > 1 chooses = df[ 'A' ] = = 4 chooses = ~(df.A = = 4 ) # 可以直接取反,等效df.A != 4 chooses = ~(df[ 'A' ] > 1 ) chooses = df[ 'A' ].isin( range ( 9 )) # A列的值是否在range(9)中 chooses = (df[ 'A' ].isin( range ( 9 ))) & (df[ 'B' ] > 1 ) # bool Series的&运算,即同时满足A列range(9)内,B列大于1 |
根据bool Series可以在行方向做筛选,iloc用不了:
1 2 3 4 5 6 7 | print (chooses.index) # Index(['1', '2', '3', '4'], dtype='object') df[chooses] # DataFrame[] df.A[chooses] # Series[] df.loc[chooses] # loc df.iloc[chooses] # 应用在iloc会报错,ValueError df = df.ix[chooses] # ix df = df.loc[:, chooses] # 应用在列方向会报错,pandas.core.indexing.IndexingError |
如果有多个bool Series可以用“|”(或),“&”(和),例如:
1 2 | df[(chooses1) | (chooses2)] df[(chooses1) & (chooses2)] |
2)按行生成的Series,index是原df的columns,可以对列方向操作进行筛选
生成行方向的bool Series:
1 2 3 | chooses = pd.Series([ True , False , True , False ], index = df.columns) chooses = df.loc[ '1' ] > 1 chooses = df.iloc[ 0 ] > 1 |
根据bool Series可以在列方向做筛选,iloc用不了:
1 2 3 4 5 | print (choose.index) # Index(['A', 'B', 'C', 'D'], dtype='object') df.loc[:, chooses] # loc df.iloc[:, chooses] # 应用在iloc会报错,ValueError df.ix[:, chooses] # ix df.loc[chooses] # 应用在行方向报错,pandas.core.indexing.IndexingError |
7.3,bool DataFrame
DataFrame可以根据bool DataFrame进行筛选,保留bool DataFrame真值对应的值,其余值置为NaN
生成bool DataFrame:
根据bool DataFrame进行筛选:
8,reindex
DataFrame.reindex也可以用来对行/列进行筛选,它不会修改原DataFrame,需另存副本:
1 2 | df.reindex(index = list ( '67' )) # 筛选出行名称为6和7的行 df.reindex(columns = list ( 'BC' )) # 筛选出列名称为B和C的列 |
9,获取行名称/列名称
有时需要获取符合条件的行名称或者列名称
9.1,通过Series获取
可以先获取行/列所在的Series,再获取该Series对应的name:
1 2 | df.iloc[ 1 ].name # 第2行的name,'6' df.iloc[:, 1 ].name # 第2列的name,'B' |
9.2,通过DataFrame获取
通过筛选获得的DataFrame,可以直接获index,columns
1 2 3 4 5 | df_sub = df[df[ 'A' ] > 4 ] df_sub.index # Index(['7', '8'], dtype='object') df_sub.columns # Index(['A', 'B', 'C', 'D'], dtype='object') df_sub.index.tolist() # ['7', '8'] df_sub.columns.tolist() # ['A', 'B', 'C', 'D'] |
10,缺失值处理
1 2 3 4 5 | df.dropna(axis = 0 , how = 'any' ) # 行里有缺失值就丢掉,如果行里所有值是缺失值才丢掉可以how='all' df.dropna(axis = 1 , how = 'any' ) # 列里有缺失值就丢掉 df.fillna(value = 0 ) # 将缺失值填为0 df.isnull() # 整个df是否有缺失值的情况,返回结果是df np. any (df.isnull()) = True ) # 只要包含有缺失值就返回True,结果是一个bool值 |