Datawhale pandas 打卡03 索引

文章目录

内容介绍

这是第三篇打卡文章。

索引器

表的列索引

取单列数据

df['Name'].head()

取多列数据

df[['Gender', 'Name']].head()

loc索引器

loc的基本用法是df.loc[]以及df.loc[,]
可以替换为多种形式
df.loc[]是选出部分行以及所有列
df.loc[
,*]是选出部分行和部分列

Datawhale pandas 打卡03 索引
使用示例表格如上,名字作为行索引

类型示例备注单个元素 df_demo.loc['Qiang Sun']

以及 df_demo.loc['Qiang Sun', 'School']

元素列表 df_demo.loc[['Qiang Sun','Quan Zhao'] ['School','Gender']]

元素切片 df_demo.loc['Gaojuan You':'Gaoqiang Qian', 'School':'Gender']

此时端点两侧需要是唯一的布尔列表 df_demo.loc[df_demo.Weight>70].head()

函数 df_demo.loc[lambda x:'Quan Zhao', lambda x:'Gender']

可以自定义函数,也可以是用匿名函数,但是返回值需要是前面四种形式

; iloc索引器

iloc的使用与loc完全类似,只不过是针对位置进行筛选,在相应的*位置处一共也有五类合法对象,分别是:整数、整数列表、整数切片、布尔列表以及函数,函数的返回值必须是前面的四类合法对象中的一个,其输入同样也为DataFrame本身。

类型示例备注整数df_demo.iloc[1, 1]第二行第二列整数列表df_demo.iloc[[0, 1], [0, 1]]前两行前两列整数切片df_demo.iloc[1: 4, 2:4]切片不包含结束端点布尔列表df_demo.iloc[(df_demo.Weight>80).values].head()不能传入Series而必须传入序列的values函数df_demo.iloc[lambda x: slice(1, 4)]传入切片为返回值的函数

query方法

query利用传入字符串的形式查询表中数据,可以直接使用列名。当列名带空格时,需要使用列名。条件的连接直接需要使用and,or,in,not in,同时条件要用括号括起来


df.query('Weight > Weight.mean()').head()

out:

Datawhale pandas 打卡03 索引

随机抽样

当我们处理大型数据,想要使用聚合函数得到数据的统计学特征时,如果直接计算,时间开销太大,于是我们需要去使用抽样方法来作为整个数据的统计特征的一个近似。
所以我们使用sample方法,它的重要参数有n, axis, frac, replace, weights

参数作用n抽样数量axis抽样的方向,0为行、1为列frac抽样比例replace是否是有放回抽样weights每个样本的抽样概率

df_sample = pd.DataFrame({'id': list('abcde'), 'value': [1, 2, 3, 4, 90]})
print(df_sample)
print('抽样结果')

df_sample.sample(3, replace = False, weights = df_sample.value)

out:

  id  value
0  a      1
1  b      2
2  c      3
3  d      4
4  e     90
抽样结果
  id  value
4  e     90
1  b      2
3  d      4

多级索引

多级索引以及表的结构

Datawhale pandas 打卡03 索引
我们可以看到多级索引可以是行索引,也可以是列索引,在行索引是school,gender,列索引是Indicator,Grade,所以索引不再是一个单独的元素,而是由对应元素构成的元组

; 多级索引的相关属性

Datawhale pandas 打卡03 索引
如果想要获得某一层的索引,利用get_level_values()得到某一层的索引

多层索引中的loc

多层索引的loc方法与单层索引没有很大区别,只需要吧单独的元素换成一个元组。同时还需要注意的是筛选时要对索引进行排序,提高效率,避免警告。


df_multi = df.set_index(['School', 'Grade'])

df_sorted = df_multi.sort_index()
df_sorted.loc[('Fudan University', 'Junior')].head()

Datawhale pandas 打卡03 索引

同时还有一种特殊的用法,可以利用对各层的元素进行笛卡尔积的结果进行筛选

res = df_multi.loc[(['Peking University', 'Fudan University'], ['Sophomore', 'Junior']), :]
res.head()

Datawhale pandas 打卡03 索引

IndexSlice对象的使用

即使在索引不重复的时候,也只能对元组整体进行切片,而不能对每层进行切片,也不允许将切片和布尔列表混合使用,引入IndexSlice对象就能解决这个问题。Slice对象一共有两种形式,第一种为loc[idx[,]]型,第二种为loc[idx[,],idx[,]]型

loc[idx[,]]型

这种情况并不能进行多层分别切片,前一个 _表示行的选择,后一个_表示列的选择,与单纯的loc是类似的:

idx=pd.IndexSlice
df_ex.loc[idx['C':, ('D', 'f'):]]

out:

Datawhale pandas 打卡03 索引

loc[idx[,],idx[,]]

这种情况能够分层进行切片,前一个idx指代的是行索引,后一个是列索引。

df_ex.loc[idx[:'B', 'a':'b'], idx['E':, 'e':]]

out:

Datawhale pandas 打卡03 索引
但是此时不可以使用函数

多次索引的构造

有三种方法构造多层索引,分别是列表,元组,笛卡尔积

pd.MultiIndex.from_tuples

my_tuple = [('a','cat'),('a','dog'),('b','cat'),('b','dog')]
pd.MultiIndex.from_tuples(my_tuple, names=['First','Second'])

out

Datawhale pandas 打卡03 索引

pd.MultiIndex.from_arrays

my_array = [list('aabb'), ['cat', 'dog']*2]
pd.MultiIndex.from_arrays(my_array, names=['First','Second'])

Datawhale pandas 打卡03 索引

pd.MultiIndex.from_product

my_list1 = ['a','b']
my_list2 = ['cat','dog']
pd.MultiIndex.from_product([my_list1, my_list2], names=['First','Second'])

out:

Datawhale pandas 打卡03 索引

索引的常用方法

索引的删除和交换

axis=1为对列处理,axis=0对行索引处理

方法备注pd.swaplevel交换两个层,pd.reorder_levels写入所有层的顺序pd.droplevel丢弃某一层的索引

用到的数据集

np.random.seed(0)
L1,L2,L3 = ['A','B'],['a','b'],['alpha','beta']
mul_index1 = pd.MultiIndex.from_product([L1,L2,L3], names=('Upper', 'Lower','Extra'))
L4,L5,L6 = ['C','D'],['c','d'],['cat','dog']
mul_index2 = pd.MultiIndex.from_product([L4,L5,L6], names=('Big', 'Small', 'Other'))
df_ex = pd.DataFrame(np.random.randint(-9,10,(8,8)), index=mul_index1,  columns=mul_index2)
df_ex

Datawhale pandas 打卡03 索引
df_ex.swaplevel(0,2,axis=1).head()

out

Datawhale pandas 打卡03 索引
df_ex.reorder_levels([2,0,1],axis=0).head()

out

Datawhale pandas 打卡03 索引
df_ex.droplevel(1,axis=1)

out

Datawhale pandas 打卡03 索引

索引属性的修改

方法描述rename_axis修改索引层的名字,常常传入字典rename对索引值做修改,需要指明levelmap对索引元组提供遍历操作;多级索引的压缩

rename_axis

df_ex.rename_axis(index={'Upper':'Changed_row'},
                  columns={'Other':'Changed_Col'}).head()

out

Datawhale pandas 打卡03 索引

rename

df_ex.rename(columns={'cat':'not_cat'}, level=2).head()

out

Datawhale pandas 打卡03 索引

map

map是定义在Index上的方法,与前面rename方法中层的函数式用法是类似的,只不过它传入的不是层的标量值,而是直接传入索引的元组,这为用户进行跨层的修改提供了遍历。例如,可以等价地写出上面的字符串转大写的操作:

df_temp = df_ex.copy()
new_idx = df_temp.index.map(lambda x: (x[0], x[1], str.upper(x[2])))
df_temp.index = new_idx
df_temp.head()

out

Datawhale pandas 打卡03 索引

索引的设置与重置

本节的表

df_new = pd.DataFrame({'A':list('aacd'), 'B':list('PQRT'), 'C':[1,2,3,4]})
df_new

out

Datawhale pandas 打卡03 索引

set_index

索引的设置可以使用set_index完成,这里的主要参数是append,表示是否来保留原来的索引,直接把新设定的添加到原索引的内层

df_new.set_index('A')

out

Datawhale pandas 打卡03 索引
df_new.set_index('A', append=True)

out

Datawhale pandas 打卡03 索引
df_new.set_index(['A', 'B'])

out

Datawhale pandas 打卡03 索引
也可以传入Series作为索引
my_index = pd.Series(list('WXYZ'), name='D')
df_new = df_new.set_index(['A', my_index])
df_new

reset_index

reset_index是set_index的逆函数,其主要参数是drop,表示是否要把去掉的索引层丢弃,而不是添加到列中。

df_new.reset_index(['D'], drop=True)

out

Datawhale pandas 打卡03 索引
如果重置了所有的索引,那么pandas会直接重新生成一个默认索引:
df_new.reset_index()

out

Datawhale pandas 打卡03 索引

索引的变形

用到的表

df_reindex = pd.DataFrame({"Weight":[60,70,80], "Height":[176,180,179]}, index=['1001','1003','1002'])
df_reindex

out

Datawhale pandas 打卡03 索引
表中给出了员工信息,需要重新制作一张新的表,要求增加一名员工的同时去掉身高列并增加性别列
df_reindex.reindex(index=['1001','1002','1003','1004'],
                   columns=['Weight','Gender'])

还有一个与reindex功能类似的函数是reindex_like,其功能是仿照传入的表索引来进行被调用表索引的变形。

df_existed = pd.DataFrame(index=['1001','1002','1003','1004'], columns=['Weight','Gender'])
df_reindex.reindex_like(df_existed)

out:

Datawhale pandas 打卡03 索引

习题

Ex1:公司员工数据集

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

Datawhale pandas 打卡03 索引
  1. 分别只使用query和loc选出年龄不超过四十岁且工作部门为Dairy或Bakery的男性。
df.query("(age)
  1. 选出员工ID号 为奇数所在行的第1、第3和倒数第2列。
df.iloc[(df.EmployeeID%2==1).values,[0,2,-2]].head()
  1. 按照以下步骤进行索引操作:
  2. 把后三列设为索引后交换内外两层
  3. 恢复中间层索引
  4. 修改外层索引名为Gender
  5. 用下划线合并两层行索引
  6. 把行索引拆分为原状态
  7. 修改索引名为原表名称
  8. 修改索引名为原表名称
  9. 修改索引名为原表名称
  10. 恢复默认索引并将列保持为原表的相对位置
df = pd.read_csv('../data/company.csv')

df=df.set_index(df.columns[-3:].tolist())
df=df.swaplevel(0,2,axis=0)

df=df.reset_index('job_title')

df.rename_axis(index={'gender':'Gender'})

new_idx=df.index.map(lambda x: x[0]+'_'+x[1])
df=df.set_index(new_idx)

new_idx=df.index.map(lambda x:tuple(x.split('_')))
df=df.set_index(new_idx)

df.index.names=('gender','department')

df.reset_index(drop=False,inplace=True)
df[['EmployeeID', 'birthdate_key', 'age', 'city_name', 'department',
       'job_title', 'gender']]

Ex2:巧克力数据集

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

Datawhale pandas 打卡03 索引
  1. 把列索引名中的\n替换为空格
df.columns=df.columns.map(lambda x:x.replace('\n',' '))
  1. 巧克力Rating评分为1至5,每0.25分一档,请选出2.75分及以下且可可含量Cocoa Percent高于中位数的样本。
df['Cocoa Percent']=df['Cocoa Percent'].apply(lambda x:x.replace('%','')).astype(float)/100
df.query("(RatingCocoa Percent.median())")
  1. 将Review Date和Company Location设为索引后,选出Review Date在2012年之后且Company Location不属于France, Canada, Amsterdam, Belgium的样本。
df=df.set_index(['Review Date','Company Location'])
idx=pd.IndexSlice
df=df.sort_index(level=0)
exclude = ['France', 'Canada', 'Amsterdam', 'Belgium']
df.loc[idx[2012:,~df.index.get_level_values(1).isin(exclude)],:]

Original: https://blog.csdn.net/Linzijiandevx/article/details/126407670
Author: Linzijiandevx
Title: Datawhale pandas 打卡03 索引

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/756314/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球