这是书籍《Pandas Cookbook》书籍第06章的代码复现,所有代码运行在Jupyter Notebook上,原讲解地址是:
https://www.jianshu.com/p/ab55e07418af
我上传代码的github地址是:
https://github.com/Asunqingwen/PandasCookbook.git
github上有该书中用到的data,里面代码会不定期更新(因为工作原因,时间不定),直到本书学习完成!
相比原讲解,会穿插一些自己的理解,水平有限,请各路大神指正。
文章目录
- 1.检查索引
- 2.求笛卡尔积
- 3.索引爆炸
- 4.用不等索引填充数值
- 5.从不同的DataFrame追加列
- 6.高亮每列的最大值
- 7.用链式方法重现idxmax
- 8.找到最常见的最大值
1.检查索引
这段主要是将索引拿出来单独讲解,因为索引底层是numpy数组,所以很多操作类似于ndarray,比如支持[]运算,切片
有许多和Series以及DataFrame相同的方法,比如min,max,isnull等;也可以直接拼接字符串,进行索引修改;还有就是通过比较运算符,得到BOOL索引
索引虽然底层是ndarry,但是本质和tuple很像,其存储对象是不可变类型,不能直接赋值修改
2.求笛卡尔积
第1部分说过索引支持集合运算,而笛卡尔积就是一种集合运算;笛卡尔积——https://baike.baidu.com/item/笛卡尔乘积/6323173?fromtitle=笛卡尔积&fromid=1434391, 这是百度百科的定义,如果按这个定义来,下图s1和s2的笛卡尔积应该有24个结果,所以索引的笛卡尔积是和索引有关的——相同索引之间进行笛卡尔积,其余的都用缺失值NaN表示
如果两组索引及其顺序完全相同,那么“+”就变成了普通加法;如果索引相同,而顺序不同,“+”还是表示笛卡尔积
3.索引爆炸
当对Series对象进行复制的时候,如果直接用“=”,则会将不同的对象名指向同一个对象,为了完全复制,必须用copy()函数
salary1和salary2虽然数据一样,但是salary1索引排序后,两个Series对象索引顺序不一样了,就可以和salary2做笛卡尔积运算了
从下图可以看出,笛卡尔积运算使得内存占用量爆炸,所以要慎用“+”
4.用不等索引填充数值
用difference()函数可以将一个索引不同于另外一个索引的值区分出来,其实这就是集合运算里面的求差运算
这里的“+”就是笛卡尔积运算,使用add()函数以及它的fill_value参数,去除了缺失值
缺失值处理后,就没有了缺失值;但是,如果一个索引值在两个进行笛卡尔积的Series都是缺失值,那么add函数使用fill_value参数也无法去除该索引值对应的缺失值
利用highlight_null()函数对缺失值NaN进行高亮显示
5.从不同的DataFrame追加列
每个部门的最高工资——对部门名进行升序排列,工资进行降序排列,那么每个部门的对应的第一个工资就是该部门的最高工资了
做比较运算,employee中没有高于最高工资的工资
如果对最高工资不去重,那么会有多个相同索引值对应不同的最高工资,那么直接赋值给employee新的一列,就会出错
选取没有重复索引值的最高工资,那就可以正确的赋值给employee新的一列了
6.高亮每列的最大值
下面这段代码算是导入数据的预处理——先做类型判断,将可以转为数值的列都转为数值类型,最后删除掉只有两个值的列(可能因为二值类型,没有求最大值的意义)
pd.options.display.max_rows = 8
#读取college数据集,INSTNM作为列
college = pd.read_csv('data/college.csv',index_col='INSTNM')
college.dtypes
#MD_WNE_P10和GRAD_DEBT_MDN_SUPP两列是对象类型,对其进行检查,发现含有字符串
college.MD_EARN_WNE_P10.iloc[0]
college.GRAD_DEBT_MDN_SUPP.iloc[0]
#降序检查
college.MD_EARN_WNE_P10.sort_values(ascending=False).head()
#可以用to_numeric,将某列的值做强制转换
cols = ['MD_EARN_WNE_P10','GRAD_DEBT_MDN_SUPP']
for col in cols:
college[col] = pd.to_numeric(college[col],errors='coerce')
college.dtypes.loc[cols]
#用select_dtypes方法过滤出数值列
college_n = college.select_dtypes(include=[np.number])
college_n.head()
#有的列只含有两个值,用nunique()方法挑出这些列
criteria = college_n.nunique() == 2
criteria.head()
#将BOOL Series传给索引运算符,生成二元列的列表
binary_cols = college_n.columns[criteria].tolist()
binary_cols
#用drop方法删除这些列
college_n2 = college_n.drop(labels=binary_cols,axis='columns')
college_n2.head()
用idxmax()方法选出每列最大值的行索引,用unique()方法选出不重复的列名
用highlight_max()函数高亮最大值行
不用[]运算符,直接调用highlight_max()函数,会高亮每一行的最大值
7.用链式方法重现idxmax
选出数值列,通过eq()函数获得列最大值的BOOL DataFrame
选出至少包括一个True值的行,用any()函数——一行/一列至少有一个True,则返回True
一共18列,最多允许18个最大值,但实际有401个,因为很多列的最大值有很多
两次累加,那么1只会出现在最大值首次出现的位置,那么用eq()函数和1比较,就能筛选出首次出现最大值的索引了
最大值16个,所得结果和idxmax()函数比较,是一样的
两种方法耗时比较,时间相差2倍左右
8.找到最常见的最大值