一.索引的进阶使用
上一篇文章里作为索引的是数字、索引名或其组成的列表、切片,这里介绍一下布尔索引
1.比较运算
先创建一个DataFrame:
df=pd.DataFrame(np.array([x**2 for x in range(1,16)]).reshape(3,5))
df.columns=list('ABCDE')
和Numpy中的数组类似,对DataFrame进行比较运算可以得到一个由布尔值组成的DataFrame:
例:print(df<100)
可得到
A B C D E
0 True True True True True
1 True True True True False
2 False False False False False
Series也是支持这种比较运算的,所以我们可以利用loc、iloc、[]等将DataFrame中的某一行或某一列提取出来进行比较运算:
例:print(df['A']<100)
实现了先将A列提取出来形成一个Series后,再对Series进行比较运算,结果如下:
0 True
1 True
2 False
df.iloc[0]<100
则提取出了第0行进行比较运算
显然得到的结果是Series类型
此外,还可以提取DataFrame其中某几行几列而形成一个新的DataFrame进行比价运算:
比如print(df.iloc[0:2,1:4]<20)
就将0、1行和1、2、3列提取出来进行了比较运算,得到了:
B C D
0 True True True
1 False False False
2.布尔索引
DataFrame支持将布尔数组/Series/DataFrame/列表作为索引
①布尔列表
提取行:
所谓布尔列表就是值为布尔型的列表,如bool_index=[True,False,True]
若将其作为索引,则可在DataFrame中提取出对应的元素:
print(df[bool_index])
A B C D E
0 1 4 9 16 25
2 121 144 169 196 225
在二维的DataFrame中,布尔列表实现的是提取行的作用,即布尔列表中的第i个元素若为True,则提取出第i行。
值得一提的是:
-
df.loc[bool_index]
与df.iloc[bool_index]
与df[bool_index]
三者的效果是一摸一样的,是按行号进行提取而不是行索引名 -
布尔列表和布尔数组实现的效果是一样的,故不再做赘述。
-
布尔列表、布尔数组只能是一维的,并且长度需要和dataframe的行数相同
————————————————————————————
提取列:
要实现提取某几列的功能只能使用iloc或loc,并且需要使用如下的写法避免其被解释为提取行
bool_columns=[True,False,True,False,True]
print(df.iloc[:,bool_columns])
结果:
A C E
0 1 9 25
1 36 64 100
2 121 169 225
注意这种方法也是按列号进行提取而不是列索引名,iloc和loc没有区别
②布尔Series
先利用字典来创建一个布尔Series:bool_index=pd.Series({0:True,1:True,2:False})
将其作为dataframe的索引后也可以实现提取行的功能:
print(df[bool_index])
A B C D E
0 1 4 9 16 25
1 36 49 64 81 100
提取列的写法要求和上面的布尔列表是一样的,下面给出一个例子:
bool_columns=pd.Series({
'A':True,
'B':False,
'C':True,
'D':False,
'E':True
})
print(df.loc[:,bool_columns])
以下几点需要注意:
-
和布尔列表/数组不同,布尔Series按行索引名进行提取,所以df.iloc不支持布尔Series
-
布尔Series长度需要和DataFrame行数/列数相同
-
提取列时方括号内
:,
要写在前面,不能写成df.loc[df.loc[0]<13,:]
,而要写df.loc[:,df.loc[0]<13]
③布尔DataFrame
由布尔值组成的DataFrame也可以作为索引,但与之前不同,由DataFrame作为索引无法实现筛选功能,值为False的位置将变为Nan,值为True的保留原值
当作为索引的DataFrame是原DataFrame的一部分时,则另外的部分由Nan填充
这部分不再具体阐述,感兴趣可自行研究
⑤总结
利用布尔索引提取行的方法:
布尔list/数组+iloc、loc、[],按行号提取
布尔Series+loc、[],按行索引名提取
利用布尔索引提取列的方法:
布尔list/数组+iloc、loc,按列号提取
布尔Series+loc,按列索引名提取
3.条件筛选
条件筛选很简单:①先通过比较运算得到一个布尔值组成的列表、数组、Series、DataFrame等; ②然后将其作为索引,即可得到符合要求的值
如:df[df['A']<50]
筛选掉了第A列大于等于50的几行
如:df.loc[:,df.loc[0]<13]
筛选掉了第0行小于等于13的几列
————————————————————————————
再进阶一下,我们可以对两个布尔Series进行进行逻辑运算,比如(df['B']>0.2)&(df['C']<0.6)
的意思就是取出第B列和第C列进行比较,若第i行同时满足B列元素大于0.2和C列元素小于0.6则值为True,否则值为False
&、|、~是位运算符,分别表示按位与、按位或、按位取反
and、or、not是逻辑运算符,分别表示且、或、非
在对布尔变量进行运算时,二者的运算结果是相同的
这里需要注意的是表达式一定要加括号,否则会报错:The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
二.缺失值的处理
DataFrame中缺失值将用Nan表示,Nan在本质上是一个浮点数
1.Nan的判断
函数isnull()可以判断DataFrame中的缺失值,返回一个由布尔类型构成的DataFrame
使用方法为:pd.isnull(df)
或df.isnull()
True表示缺失,False表示不缺失
2.Nan的删除
函数dropna用于删除缺失值:
DataFrame.dropna( axis=0, how=‘any’, thresh=None, subset=None, inplace=False)
重要参数详解:
①how表示删除的方式,若为any表示只要有一个Nan就删除该行(列),若为all则表示只有全部值缺失的行(列)会被删除
②axis表示删除的轴,若为0或“index”表示删除行,若为1或“columns”表示删除列
③subset参数是一个列表,指定在哪个范围内删除行、列
此外还有一种方法:通过isnull和布尔索引结合的方式来删除缺失值Nan
3.Nan的填充
对于缺失值一般有两种处理方式:删除或填充
可以用fillna()函数将缺失值填充为指定的值
三.排序
排序函数:
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind=‘quicksort’, na_position=‘last’)
重要参数讲解:
①by:列名或行名,即指定按哪一行/列进行排序。可以是由行名/列名组成的列表,先按列表的第一个行名/列名进行排序,相等的情况下按第二个行名/列名进行排序
②ascending:为True表示升序,为False表示降序
③inplace:为True表示修改原DataFrame的值,False表示不修改
四.其他
1.基本统计分析
函数describe可以提供一些DataFrame的基本信息,我们可以根据其对DataFrame有一个大致的了解并发现异常值
例:
print(df.describe())
A B C D E
count 3.000000 3.000000 3.000000 3.000000 3.000000
mean 52.666667 65.666667 80.666667 97.666667 116.666667
std 61.711695 71.472605 81.291656 91.150059 101.036297
min 1.000000 4.000000 9.000000 16.000000 25.000000
25% 18.500000 26.500000 36.500000 48.500000 62.500000
50% 36.000000 49.000000 64.000000 81.000000 100.000000
75% 78.500000 96.500000 116.500000 138.500000 162.500000
max 121.000000 144.000000 169.000000 196.000000 225.000000