pandas 学习3(索引)

Reference:https://datawhalechina.github.io/joyful-pandas/build/html/%E7%9B%AE%E5%BD%95/ch3.html#id18

这次学习的是索引的相关内容
一、索引器

(1)表的列索引
主通过列名从DataFrameDataFrame中取出相应的列,返回值类型为Series , 上个代码。

df = pd.read_csv('E:\\learn python\\numpy&pandas\\learn_pandas.csv',
                 usecols= ['School', 'Grade', 'Name', 'Gender','Weight', 'Transfer'])
res =  df['Name'].head()#取出该列,去多列类似 如df['Name','Grade'].head()
print(res)
"""
0      Gaopeng Yang
1    Changqiang You
2           Mei Sun
3      Xiaojuan Sun
4       Gaojuan You
Name: Name, dtype: object
"""

(2)序列的行索引
用 [item] 来取出序列所对应的值,若对应单个值则返回单个值,对应多个值则返回多个值,上个代码。

s = pd.Series([1, 2, 3, 4, 5, 6],
                    index=['a', 'b', 'a', 'a', 'a', 'c'])

res1 = s['a']
res2 = s['b']
print(res1)
"""
a    1
a    3
a    4
a    5
"""
print(res2)#2

(3)loc索引器
loc 索引器的一般形式是 loc[*, *] ,第一个代表行,第二个 * 代表列,如果单纯的写 loc[]则代表行的选择。上代码

df_demo = df.set_index('Name')

res = df_demo.head()

print(res)
"""
                                       School      Grade  ... Weight  Transfer
Name                                                      ...                 
Gaopeng Yang    Shanghai Jiao Tong University   Freshman  ...   46.0         N
Changqiang You              Peking University   Freshman  ...   70.0         N
Mei Sun         Shanghai Jiao Tong University     Senior  ...   89.0         N
Xiaojuan Sun                 Fudan University  Sophomore  ...   41.0         N
Gaojuan You                  Fudan University  Sophomore  ...   74.0         N

"""
res2 = df_demo.loc['Qiang Sun']
print(res2)
"""
                                School      Grade  Gender  Weight Transfer
Name                                                                        
Qiang Sun            Tsinghua University     Junior  Female    53.0        N
Qiang Sun            Tsinghua University  Sophomore  Female    40.0        N
Qiang Sun  Shanghai Jiao Tong University     Junior  Female     NaN        N
"""

觉得当*为布尔列表的时候需要注意一下,估计以后常用,上个代码

res3 = df_demo.loc[df_demo.Weight>70].head()
print(res3)
"""
                                     School      Grade Gender  Weight Transfer
Name                                                                           
Mei Sun        Shanghai Jiao Tong University     Senior   Male    89.0        N
Gaojuan You                 Fudan University  Sophomore   Male    74.0        N
Xiaopeng Zhou  Shanghai Jiao Tong University   Freshman   Male    74.0        N
Xiaofeng Sun             Tsinghua University     Senior   Male    71.0        N
Qiang Zheng    Shanghai Jiao Tong University     Senior   Male    87.0        N

"""

(4)iloc索引器
iloc的用法和loc的用法相同,但它是针对位置进行筛选

df_demo.iloc[1, 1] #对所传入表的第行第二列取出操作
df_demo.iloc[[0, 1], [0, 1]] # 前两行前两列进行取出操作
df_demo.iloc[1: 4, 2:4] # 进行切片操作,切片不包含结束端点

***在使用布尔列表的时候要特别注意,不能传入 Series 而必须传入序列的 values ,否则会报错。因此,在使用布尔筛选的时候还是应当优先考虑 loc 的方式。***这点要注意(感觉还是loc的方法适合我,我肯定要忘记加.values的,上个代码,两个方法做个对比)

df_demo.loc[df_demo.Weight>70].head()##loc的
df_demo.iloc[(df_demo.Weight>80).values].head()### iloc的

(5)query方法
参考文档给出这样的解释:在 pandas 中,支持把字符串形式的查询表达式传入 query 方法来查询数据,其表达式的执行结果必须返回布尔列表。在进行复杂索引时,由于这种检索方式无需像普通方法一样重复使用 DataFrame 的名字来引用列名,一般而言会使代码长度在不降低可读性的前提下有所减少。 (说白了,就是方便了,代码简洁了,上个代码。)

res = df.query('((School == "Fudan University")&'
                    ' (Grade == "Senior")&'
                    ' (Weight > 70))|'
                    '((School == "Peking University")&'
                    ' (Grade != "Senior")&'
                ' (Weight > 80))')

print(res)
"""
          School     Grade            Name Gender  Weight Transfer
38   Peking University  Freshman       Qiang Han   Male    87.0        N
66    Fudan University    Senior  Chengpeng Zhou   Male    81.0        N
99   Peking University  Freshman  Changpeng Zhao   Male    83.0        N
131   Fudan University    Senior  Chengpeng Qian   Male    73.0        Y
"""

另外注意如果所选的列名有空格的话用这样的形式 col name 来进行选取。

二、多索引

多索引的形式类似这样的
在这里插入图片描述

先构造个行多索引
在这里插入图片描述
当传入元组列表或单个元组或返回前二者的函数时,需要先进行索引排序以避免性能警告:

当检索自己想要的索引条件时,用法loc和iloc方法类似,上代码,举栗子。


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

#print(df_multi.head())


df_sorted = df_multi.sort_index()
res = df_sorted.loc[('Fudan University', 'Junior')].head()
print(res)
"""
School           Grade                                         
Fudan University Junior      Yanli You  Female    48.0        N
                 Junior  Chunqiang Chu    Male    72.0        N
                 Junior   Changfeng Lv    Male    76.0        N
                 Junior     Yanjuan Lv  Female    49.0      NaN
                 Junior  Gaoqiang Zhou  Female    43.0        N

"""

res2 = df_sorted.loc[[('Fudan University', 'Senior'),
              ('Shanghai Jiao Tong University', 'Freshman')]].head()

print(res2)
"""
           Name  Gender  Weight Transfer
School           Grade                                           
Fudan University Senior  Chengpeng Zheng  Female    38.0        N
                 Senior        Feng Zhou  Female    47.0        N
                 Senior        Gaomei Lv  Female    34.0        N
                 Senior        Chunli Lv  Female    56.0        N
                 Senior   Chengpeng Zhou    Male    81.0        N
"""

IndexSlice对象
主要功能是能够对每层的进行切片,slice 总共分为两种:
第一种为 loc[idx[*,*]] 型,
第二种为 loc[idx[*,*],idx[*,*]]

首先构造一个索引不重复的 DataFrame :

np.random.seed(0)
L1,L2 = ['A','B','C'],['a','b','c']
mul_index1 = pd.MultiIndex.from_product([L1,L2],names=('Upper', 'Lower'))
L3, L4 = ['D', 'E', 'F'], ['d', 'e', 'f']
mul_index2 = pd.MultiIndex.from_product([L3,L4],names=('Big', 'Small'))
df_ex = pd.DataFrame(np.random.randint(-9,10,(9,9)),
                                    index=mul_index1,
                                    columns=mul_index2)

在这里插入图片描述
loc[idx[*,*]] 型 前一个 * 表示行的选择,后一个 * 表示列的选择,上个代码。
在这里插入图片描述

在这里插入图片描述
loc[idx[*,*],idx[*,*]] 型,前一个 idx 指代的是行索引,后一个是列索引。
在这里插入图片描述
三、索引的常用方法
1、索引层的交换和删除

先构造一个三级索引如图
在这里插入图片描述
索引层的交换有swaplevel和 reorder_levels 两种方法,前者只能交换两层,后者可以交换任意两层。

df_ex.swaplevel(0,2,axis=1).head()#列索引的第一层和第三层交换
 df_ex.reorder_levels([2,0,1],axis=0).head() # 列表数字指代原来索引中的层号,原先是012,现在变为201

在这里插入图片描述删除索引用droplevel
在这里插入图片描述
四、练习
Ex1:公司员工数据集

现有一份公司员工数据集:
在这里插入图片描述

1.分别只使用 query 和 loc 选出年龄不超过四十岁且工作部门为 Dairy 或 Bakery 的男性。

2 选出员工 ID 号 为奇数所在行的第1、第3和倒数第2列。

3.按照以下步骤进行索引操作:

把后三列设为索引后交换内外两层

恢复中间一层

修改外层索引名为 Gender

用下划线合并两层行索引

把行索引拆分为原状态

修改索引名为原表名称

恢复默认索引并将列保持为原表的相对位置

解:1、querry的方法

res1 = df.query(    '((age<=40)&(department =="Dairy" ) & '
             '(gender == "M" ))|'
             
             '((age<=40)&(department =="Bakery" ) & '
                '(gender == "M"))'

 )
print(res1)

loc的方法

def conditicon(x):
    condition1 = x.age <= 40
    condition2_1 = x.department == 'Dairy'
    condition2_2 = x.department == 'Bakery'
    condition2 = condition2_1 | condition2_2
    condition_3 = x.gender == 'M'
    res = condition1 & condition2 & condition_3
    return res
    #pass

res2 = df.loc[conditicon]
print(res2)

2、
我的想法是:先用loc选出id为奇数的,再用iloc取列,代码如下

res1 = df.loc[df.EmployeeID%2==1]
res2 = res1.iloc[:,[0,2,-2]]
print(res2)

参考答案:(我就没想到…)

df.iloc[(df.EmployeeID%2==1).values,[0,2,-2]].head()

3、
好吧,我是学渣,就做了一半。
原答案:
在这里插入图片描述
我的半成品:

df_op = df.copy()
step_1 = df_op.set_index(df_op.columns[-3:].tolist()).swaplevel(0,2,axis=0)
print(step_1)
step_2 = step_1.reset_index(level=1)
step_3 = step_2.rename_axis(index={'gender:Gender'})
# print(step_3)
step_4 = step_3.copy()
step_4.index = step_3.index.map(lambda x:'_'.join(x))
print(step_4)

剩下一道题不做了,考试了快,得赶紧复习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值