微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Pandas进阶叁 索引

Pandas进阶叁 索引

pandas进阶系列根据datawhale远昊大佬的joyful pandas教程写一些自己的心得和补充,本文部分引用了原教程,并参考了《利用Python进行数据分析》、pandas官网

这几天太忙了,这次没怎么总结学习的内容,先把做的作业题放一下,晚上刚从外地回来,明天开始有更多时间了,这次打卡内容有些单薄,希望助教大大理解(题目思考过程随后补上)

【练一练】

select_dtypes一个实用函数,它能够从表中选出相应类型的列,若要选出所有数值型的列,只需使用.select_dtypes('number'),请利用布尔列表选择的方法结合DataFramedtypes属性learn_pandas数据集上实现这个功能

在做这道习题的时候发现pandas里没有专门的number类型,由于在第一期学习numpy的时候我看过numpy dtype的类型层级结构,所以记得numpy的dtype里有number类型,numpy的层级结构如图所示:
dtype层级结构[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B3PSzzzr-1608650718583)(attachment:image-2.png =500*400)]
图中有些类有下划线,是为了和python内置类有所区分。numpy包将这些类型作为整个包的全局常量,在这道题中我用了np.issubdtype来判断一个类型是不是另一个类型的子类,pandas的数据的dtype也是通过numpy实现的,所以在这道题中我遍历所有列,判断其类型是不是np.number的子类,来求出一个DataFrame实例的所有数值型的列。

import numpy as np
import pandas as pd
df = pd.read_csv('../data/learn_pandas.csv', usecols = ['School', 'Grade', 'Name', 'Gender', 'Weight', 'Transfer'])
df_demo = df.copy()
df_demo[[c for c in df_demo.columns if np.issubdtype(df_demo[c].dtype, np.number)]].head()
Weight
046.0
170.0
289.0
341.0
474.0
%%timeit
df_demo = df.copy()
df_demo[[c for c in df_demo.columns if np.issubdtype(df_demo[c].dtype, np.number)]].head()
1.05 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
df_demo.select_dtypes('number').head()
898 µs ± 8.67 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

【练一练】

与单层索引类似,若存在重复元素,则不能使用切片,请去除重复索引后给出一个元素切片的例子。

【END】

此外,在多级索引中的元组有一种特殊的用法,可以对多层的元素进行交叉组合后索引,但同时需要指定loc的列,全选则用:表示。其中,每一层需要选中的元素用列表存放,传入loc的形式为[(level_0_list, level_1_list), cols]。例如,想要得到所有北大和复旦的大二大三学生,可以如下写出:

【练一练】

尝试在rename_axis中使用函数完成与例子中一样的功能

【END】

对于整个索引的元素替换,可以利用迭代器实现:

五、练习

Ex1:公司员工数据集

现有一份公司员工数据集:

df = pd.read_csv('../data/company.csv')
df.head(3)
EmployeeIDbirthdate_keyagecity_namedepartmentjob_titlegender
013181/3/195461VancouverExecutiveCEOM
113191/3/195758VancouverExecutiveVP StoresF
213201/2/195560VancouverExecutiveLegal CounselF
  1. 分别只使用queryloc选出年龄不超过四十岁且工作部门为DairyBakery的男性。
  2. 选出员工ID号 为奇数所在行的第1、第3和倒数第2列。
  3. 按照以下步骤进行索引操作:
  • 把后三列设为索引后交换内外两层
  • 恢复中间一层
  • 修改外层索引名为Gender
  • 用下划线合并两层行索引
  • 把行索引拆分为原状态
  • 修改索引名为原表名称
  • 恢复认索引并将列保持为原表的相对位置
dpt = ['Dairy', 'Bakery']
df.query("(age <= 40)&(department == @dpt)&(gender=='M')").head(3)
df.loc[(df.age<=40)&df.department.isin(dpt)&(df.gender=='M')].head(3)
df.iloc[(df.EmployeeID%2==1).values,[0,2,-2]].head()
df_op = df.copy()
df_op = df_op.set_index(df_op.columns[-3:].tolist()).swaplevel(0,2,axis=0)
df_op = df_op.reset_index(level=1)
df_op = df_op.rename_axis(index={'gender':'Gender'})
df_op.index = df_op.index.map(lambda x:'_'.join(x))
df_op.index = df_op.index.map(lambda x:tuple(x.split('_')))
df_op = df_op.rename_axis(index=['gender', 'department'])
df_op = df_op.reset_index().reindex(df.columns, axis=1)
df_op.equals(df)

Ex2:巧克力数据集

现有一份关于巧克力评价的数据集:

df = pd.read_csv('../data/chocolate.csv')
df.head(3)
CompanyReview\nDateCocoa\nPercentCompany\nLocationrating
0A. Morin201663%France3.75
1A. Morin201570%France2.75
2A. Morin201570%France3.00
  1. 把列索引名中的\n替换为空格。
  2. 巧克力rating评分为1至5,每0.25分一档,请选出2.75分及以下且可可含量Cocoa Percent高于中位数的样本。
  3. Review DateCompany Location设为索引后,选出Review Date在2012年之后且Company Location不属于France, Canada, Amsterdam, Belgium的样本。
df = pd.read_csv('../data/chocolate.csv')
df.columns = [' '.join(i.split('\n')) for i in df.columns]
df.head(3)
df['Cocoa Percent'] = df['Cocoa Percent'].apply(lambda x:float(x[:-1])/100)
df.query('(rating<3)&(`Cocoa Percent`>`Cocoa Percent`.median())').head(3)
idx = pd.IndexSlice
exclude = ['France', 'Canada', 'Amsterdam', 'Belgium']
res = df.set_index(['Review Date', 'Company Location']).sort_index(level=0)
res.loc[idx[2012:,~res.index.get_level_values(1).isin(exclude)],:].head(3)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐