【Pandas学习笔记Task03】:索引

import numpy as np
import pandas as pd 

一、索引器

1.列索引

对于DataFrame而言,可以通过传入某个列名、或者多个列名的列表来获取该列的值。返回的是Series或者DataFrame。

df = pd.read_csv('data/learn_pandas.csv', usecols=['School', 'Grade', 'Name', 'Gender', 'Weight', 'Transfer'])
df['Name'].head()
0      Gaopeng Yang
1    Changqiang You
2           Mei Sun
3      Xiaojuan Sun
4       Gaojuan You
Name: Name, dtype: object
df[['School','Grade']].head()
SchoolGrade
0Shanghai Jiao Tong UniversityFreshman
1Peking UniversityFreshman
2Shanghai Jiao Tong UniversitySenior
3Fudan UniversitySophomore
4Fudan UniversitySophomore

2.行索引

这里主要是Series的行索引,针对Series的行索引与DataFrame的列索引相似。

s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'a', 'a', 'c']) 
s['a'] #因为是Series,只有单个值,所以可直接使用索引。DataFrame直接用则是列索引 
a    1
a    3
a    4
dtype: int64
s['b':'c']# 如果要取出某两个索引之间的元素,要保证这两个索引在整个索引中唯一出现,则可以使用切片。
b    2
a    3
a    4
c    5
dtype: int64

3.loc iloc选择器

针对DataFrame取行,可利用loc(元素)与iloc(位置)选择器。
loc[*,*]中的*代表行与列,有五类合法对象:单个元素、元素列表、元素切片、布尔列表以及函数.可以组合使用(比如行用切片,列用布尔列表)

df_demo = df.set_index('Name')
df_demo.head()
SchoolGradeGenderWeightTransfer
Name
Gaopeng YangShanghai Jiao Tong UniversityFreshmanFemale46.0N
Changqiang YouPeking UniversityFreshmanMale70.0N
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Xiaojuan SunFudan UniversitySophomoreFemale41.0N
Gaojuan YouFudan UniversitySophomoreMale74.0N
# df_demo.loc[0].head() 
# 我觉得用loc,一般是将默认的数值索引设为某些字符串时使用(如Name),虽然这样也正确。但这样不如用iloc
df_demo.loc['Mei Sun'].head()# 这里*代表的是行索引的某个值
SchoolGradeGenderWeightTransfer
Name
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Mei SunShanghai Jiao Tong UniversityJuniorFemale50.0N
同时选择行与列。返回 是一个Series或者一个元素。
df_demo.loc['Qiang Sun', 'School'] 
Name
Qiang Sun              Tsinghua University
Qiang Sun              Tsinghua University
Qiang Sun    Shanghai Jiao Tong University
Name: School, dtype: object
df_demo.loc['Quan Zhao', 'School']
'Shanghai Jiao Tong University'
# 这里的切片和前面Series使用字符串索引一样;切片的俩位置字符要唯一
df_demo.loc['Gaopeng Yang':'Gaojuan You','School':'Gender']
# 这里若用Mei Sun,会报错。因为Mei Sun不唯一。
SchoolGradeGender
Name
Gaopeng YangShanghai Jiao Tong UniversityFreshmanFemale
Changqiang YouPeking UniversityFreshmanMale
Mei SunShanghai Jiao Tong UniversitySeniorMale
Xiaojuan SunFudan UniversitySophomoreFemale
Gaojuan YouFudan UniversitySophomoreMale

布尔列表,也就是根据某些条件来筛选出行来,很常见.布尔列表要与DataFrame的行数,(列数)相同

df_demo.loc[df_demo.Weight > 70].head()# 这里选出体重大于70kg的,这个比较返回的是一个列表,长度是Weight的那一列个数
SchoolGradeGenderWeightTransfer
Name
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Gaojuan YouFudan UniversitySophomoreMale74.0N
Xiaopeng ZhouShanghai Jiao Tong UniversityFreshmanMale74.0N
Xiaofeng SunTsinghua UniversitySeniorMale71.0N
Qiang ZhengShanghai Jiao Tong UniversitySeniorMale87.0N
df_demo.loc[df_demo.Grade.isin(['Freshman', 'Senior'])].head()# isin传的是一个列表
# 这里去掉loc,单用df_demo[df_demo.Grade.isin(['Freshman', 'Senior'])]也行

isin是Series的一个函数,用于数据清洗。传入的是一个列表值,然后去看看isin前面的Grade列的每个值是否包含传入的列表值,返回的是一个布尔列表,长度为样本数,因为每行的Grade都判断。

SchoolGradeGenderWeightTransfer
Name
Gaopeng YangShanghai Jiao Tong UniversityFreshmanFemale46.0N
Changqiang YouPeking UniversityFreshmanMale70.0N
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Xiaoli QianTsinghua UniversityFreshmanFemale51.0N
Qiang ChuShanghai Jiao Tong UniversityFreshmanFemale52.0N

对于复合条件,用|,&,~(取反)来组合,这里启发了task01的EX1的第3小问,为什么用的是&而不是and。

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

# df_demo.dtypes.isin(['float64']) # Series.
df_demo.loc[:,df_demo.dtypes.isin(['float64'])].head() # 行用的切片,列用的布尔列表

思路:选择出数值型的列,首先要先找出DataFrame所有列的类型,这里用dtypes得到(DataFrame列本质也是Series)。然后利用isin判断哪些列类型是数值的(这里只设置了float64),设置对应的布尔值,然后利用loc的布尔列表形式去访问就行了。

Weight
Name
Gaopeng Yang46.0
Changqiang You70.0
Mei Sun89.0
Xiaojuan Sun41.0
Gaojuan You74.0
df_demo.select_dtypes('number').head()
Weight
Name
Gaopeng Yang46.0
Changqiang You70.0
Mei Sun89.0
Xiaojuan Sun41.0
Gaojuan You74.0
# 注意不要使用链式赋值
df_chain = pd.DataFrame([[0,0],[1,0],[-1,0]],columns=list('AB'))
df_chain
AB
000
110
2-10
df_chain.loc[df_chain.A != 0, 'B'] = 1 # loc可以精确选择到多个某行某列,可以执行修改值。
df_chain
AB
000
111
2-11
# iloc选择器.与loc相似,只不过iloc是针对位置的。
df_demo.iloc[1, 2] # 只有一个元素,返回的是一个str
'Male'
df_demo.iloc[lambda x: slice(1, 4)] #切片函数
SchoolGradeGenderWeightTransfer
Name
Changqiang YouPeking UniversityFreshmanMale70.0N
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Xiaojuan SunFudan UniversitySophomoreFemale41.0N
# 在iloc使用布尔列表的时候,传入的不能是Series,而是values()。
# 因此,在使用布尔筛选的时候还是应当优先考虑 loc 的方式
df_demo.iloc[(df_demo.Weight > 70).values].head()
SchoolGradeGenderWeightTransfer
Name
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Gaojuan YouFudan UniversitySophomoreMale74.0N
Xiaopeng ZhouShanghai Jiao Tong UniversityFreshmanMale74.0N
Xiaofeng SunTsinghua UniversitySeniorMale71.0N
Qiang ZhengShanghai Jiao Tong UniversitySeniorMale87.0N
# (df_demo.Weight > 70).values
(df_demo.Weight>70).dtype #前面是一个Series的bool列表
dtype('bool')

通过报错’numpy.ndarray’ object has no attribute 'head’发现传入的是一个np数组,所以就可以理解为什么要是values而不能是Series了,因为iloc代表的是索引,所以用np列表。

4.query方法

# 这是利用loc选择器传入布尔列表进行取值
df_demo.loc[df_demo.Weight > df_demo.Weight.mean()].head()
SchoolGradeGenderWeightTransfer
Name
Changqiang YouPeking UniversityFreshmanMale70.0N
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Gaojuan YouFudan UniversitySophomoreMale74.0N
Xiaopeng ZhouShanghai Jiao Tong UniversityFreshmanMale74.0N
Xiaomei ZhouTsinghua UniversitySeniorFemale57.0N
#利用query方法
df_demo.query('(Weight > Weight.mean())').head()

这里query创建了DataFrame(可以理解为query前面的DataFrame),因此传入的字符串可以省略DataFrame,减少代码量。

SchoolGradeGenderWeightTransfer
Name
Changqiang YouPeking UniversityFreshmanMale70.0N
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Gaojuan YouFudan UniversitySophomoreMale74.0N
Xiaopeng ZhouShanghai Jiao Tong UniversityFreshmanMale74.0N
Xiaomei ZhouTsinghua UniversitySeniorFemale57.0N

二、多级索引

1.多级索引及其表的结构


np.random.seed(0)
multi_index = pd.MultiIndex.from_product([list('ABCD'),df.Gender.unique()],names=('School','Gender'))
multi_column = pd.MultiIndex.from_product([['Height', 'Weight'], df.Grade.unique()],names=('Indicator','Grade'))
df_multi = pd.DataFrame(np.c_[(np.random.randn(8,4)*5+163).tolist(),
                             (np.random.randn(8,4)*5+65).tolist()],
                       index=multi_index,
                       columns=multi_column).round(1)
df_multi
IndicatorHeightWeight
GradeFreshmanSeniorSophomoreJuniorFreshmanSeniorSophomoreJunior
SchoolGender
AFemale171.8165.0167.9174.260.655.163.365.8
Male172.3158.1167.8162.271.271.063.163.5
BFemale162.5165.1163.7170.359.857.956.574.8
Male166.8163.6165.2164.762.562.858.768.9
CFemale170.5162.0164.6158.756.963.960.566.9
Male150.2166.3167.3159.362.459.164.967.1
DFemale174.3155.7163.2162.165.366.561.863.2
Male170.7170.3163.8164.961.663.260.956.4

多级索引的名字和值可以通过names与values来获取

df_multi.index.names
FrozenList(['School', 'Gender'])
df_multi.index.values
array([('A', 'Female'), ('A', 'Male'), ('B', 'Female'), ('B', 'Male'),
       ('C', 'Female'), ('C', 'Male'), ('D', 'Female'), ('D', 'Male')],
      dtype=object)
df_multi.index.get_level_values(1)# 得到某一层的索引
Index(['Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male'], dtype='object', name='Gender')
# 多级索引中的loc索引器
# (行为多级索引,列为单索引)
df_multi = df.set_index(['School', 'Grade'])
df_multi = df_multi.sort_index()# 先排序,避免后续进行loc或者iloc的性能警告
df_multi.head()
NameGenderWeightTransfer
SchoolGrade
Fudan UniversityFreshmanChangqiang YangFemale49.0N
FreshmanGaoqiang QinFemale63.0N
FreshmanGaofeng ZhaoFemale43.0N
FreshmanYanquan WangFemale55.0N
FreshmanFeng WangMale74.0N

2.多级索引的loc选择器

df_multi.loc[('Fudan University', 'Junior')].head()#相当于之前单级索引的单个元素。
NameGenderWeightTransfer
SchoolGrade
Fudan UniversityJuniorYanli YouFemale48.0N
JuniorChunqiang ChuMale72.0N
JuniorChangfeng LvMale76.0N
JuniorYanjuan LvFemale49.0NaN
JuniorGaoqiang ZhouFemale43.0N
df_multi.loc[[('Fudan University', 'Senior'),('Shanghai Jiao Tong University', 'Freshman')]].head()
NameGenderWeightTransfer
SchoolGrade
Fudan UniversitySeniorChengpeng ZhengFemale38.0N
SeniorFeng ZhouFemale47.0N
SeniorGaomei LvFemale34.0N
SeniorChunli LvFemale56.0N
SeniorChengpeng ZhouMale81.0N
df_multi.loc[df_multi.Weight > 70].head() #里面的布尔列表是一个Series的布尔列表。
NameGenderWeightTransfer
SchoolGrade
Fudan UniversityFreshmanFeng WangMale74.0N
JuniorChunqiang ChuMale72.0N
JuniorChangfeng LvMale76.0N
SeniorChengpeng ZhouMale81.0N
SeniorChengpeng QianMale73.0Y
# 对多层元素进行交叉组合后索引,但同时需要指定列,全选用:
# 想要得到所有北大和复旦的大二大三学生
# 传的是一个元组,里面有两个列表。分别从两个列表选一个元素组成一个元组
df_multi.loc[(['Peking University','Fudan University'],['Sophomore', 'Junior']),:].head()
NameGenderWeightTransfer
SchoolGrade
Peking UniversitySophomoreChangmei XuFemale43.0N
SophomoreXiaopeng QinMaleNaNN
SophomoreMei XuFemale39.0N
SophomoreXiaoli ZhouFemale55.0N
SophomorePeng HanFemale34.0NaN
#选出北大的大三学生和复旦的大二学生
df_multi.loc[[('Peking University', 'Junior'),('Fudan University', 'Sophomore')]].head()
NameGenderWeightTransfer
SchoolGrade
Peking UniversityJuniorJuan XuFemaleNaNN
JuniorChangjuan YouFemale47.0N
JuniorGaoli XuFemale48.0N
JuniorGaoquan ZhouMale70.0N
JuniorQiang YouFemale56.0N

3.多级索引的IndexSlice对象

多级索引中,即使在索引不重复的时候,也只能对元组整体进行切片,而不能对每层进行切片,也不允许将切片和布尔列表混合使用,引入 IndexSlice 对象就能解决这个问题。

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)
df_ex
BigDEF
Smalldefdefdef
UpperLower
Aa36-9-6-6-209-5
b-33-8-3-258-44
c-107-466-99-6
Ba85-2-9-80-91-6
b29-7-9-9-5-4-3-1
c86-501-8-8-20
Ca-6-3259-95-63
b12-5-3-56-63-5
c-156-66478-4

loc[idx[*,*]]两个*代表行与列。

idx = pd.IndexSlice # 使用silice对象前先进行定义
df_ex.loc[idx['C':,('D','f'):]]
BigDEF
Smallfdefdef
UpperLower
Ca259-95-63
b-5-3-56-63-5
c6-66478-4

loc[idx[*,*],idx[*,*]] 两个的话,idx就代表行与列,然后里面的*代表索引层

df_ex.loc[idx[:'A','b':], idx['E':,'e':]]
BigEF
Smallefef
UpperLower
Ab-25-44
c669-6

4.多级索引构造

除了使用set_index(‘索引名字’)之外(将DataFrame列索引当做新行索引),自己构造。

# from_tuples 根据传入由元组组成的列表进行构造索引的值。一个元组代表一组多级索引(可以理解为一行)
my_tuple = [('a', 'cat'),('a', 'dog'),('b', 'cat'),('b', 'dog')]
my_index = pd.MultiIndex.from_tuples(my_tuple, names=['First','Second'])
df_multi_tuples = pd.DataFrame(np.random.randint(1,9,(4,2)),
                              index=my_index)
df_multi_tuples
01
FirstSecond
acat24
dog18
bcat67
dog12
# from_arrays根据传入的几个列表,对应位置构成多级索引的一行
my_array = [list('aabb'),['cat', 'dog'] * 2]
my_array_index = pd.MultiIndex.from_arrays(my_array, names=['First', 'Sceond'])
df_multi_arrays = pd.DataFrame(np.random.randint(1,8,(4,2)),
                              index = my_array_index)
df_multi_arrays
01
FirstSceond
acat35
dog31
bcat64
dog33
# from_product 根据给定多个列表的笛卡尔积进行构造
#这里product和array有区别
# array直接将列表对应位置结合;product是取两个列表的元素的笛卡尔积
my_list1 = ['a' ,'b']
my_list2 = ['cat', 'dog']
my_product_index = pd.MultiIndex.from_product([my_list1, my_list2],
                                             names=['First','Second'])
df_multi_products = pd.DataFrame(np.random.randn(4,2),
                                index=my_product_index)
df_multi_products
01
FirstSecond
acat0.0665170.302472
dog-0.634322-0.362741
bcat-0.672460-0.359553
dog-0.813146-1.726283

三、索引的常用方法.

1.索引层的交换和删除

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.columns
MultiIndex([('C', 'c', 'cat'),
            ('C', 'c', 'dog'),
            ('C', 'd', 'cat'),
            ('C', 'd', 'dog'),
            ('D', 'c', 'cat'),
            ('D', 'c', 'dog'),
            ('D', 'd', 'cat'),
            ('D', 'd', 'dog')],
           names=['Big', 'Small', 'Other'])
df_ex.swaplevel(0 ,2, axis= 1).head()#axis = 1,代表列。0,2是列索引的值的索引
# 只能交换两个层
Othercatdogcatdogcatdogcatdog
Smallccddccdd
BigCCCCDDDD
UpperLowerExtra
Aaalpha36-9-6-6-209
beta-5-33-8-3-258
balpha-44-107-466
beta-99-685-2-9-8
Baalpha0-91-629-7-9
df_ex.reorder_levels([2,1,0],axis=1).head()
# 可以交换任意层
Othercatdogcatdogcatdogcatdog
Smallccddccdd
BigCCCCDDDD
UpperLowerExtra
Aaalpha36-9-6-6-209
beta-5-33-8-3-258
balpha-44-107-466
beta-99-685-2-9-8
Baalpha0-91-629-7-9
# droplevel删除某一层索引
# df_ex.droplevel(1, axis = 1)
# df_ex.droplevel([0, 1], axis = 1)

2.索引属性的修改

#rename_axis对索引层名字的修改,通常为字典序列
df_ex.rename_axis(index={'Extra':'changed_row'},
                 columns={'Other':'changed_col'}).head()
BigCD
Smallcdcd
changed_colcatdogcatdogcatdogcatdog
UpperLowerchanged_row
Aaalpha36-9-6-6-209
beta-5-33-8-3-258
balpha-44-107-466
beta-99-685-2-9-8
Baalpha0-91-629-7-9
# rename可以改索引值,如果是多级索引需要指定修改层号level
df_ex.rename(columns={'cat':'not_cat'},level=2).head()
BigCD
Smallcdcd
Othernot_catdognot_catdognot_catdognot_catdog
UpperLowerExtra
Aaalpha36-9-6-6-209
beta-5-33-8-3-258
balpha-44-107-466
beta-99-685-2-9-8
Baalpha0-91-629-7-9
df_ex.rename(index=lambda x: str.upper(x),level=2).head()
BigCD
Smallcdcd
Othercatdogcatdogcatdogcatdog
UpperLowerExtra
AaALPHA36-9-6-6-209
BETA-5-33-8-3-258
bALPHA-44-107-466
BETA-99-685-2-9-8
BaALPHA0-91-629-7-9

对整个索引的元素替换,可以利用迭代器实现。这里iter用于生成迭代器;next从迭代器选元素。这里我以为迭代如果数量不够会从头再循环着来,发现并不是,会报错(还是没有理解到位的缘故)。

new_values = iter(list('abcdefgh'))
df_ex.rename(index=lambda x:next(new_values),level=2)
BigCD
Smallcdcd
Othercatdogcatdogcatdogcatdog
UpperLowerExtra
Aaa36-9-6-6-209
b-5-33-8-3-258
bc-44-107-466
d-99-685-2-9-8
Bae0-91-629-7-9
f-9-5-4-3-186-5
bg01-8-8-20-6-3
h259-95-631
df_temp = df_ex.copy()
# 用map等价写字符串转大写的操作
new_idx = df_temp.index.map(lambda x:(x[0],
                                     x[1],
                                     str.upper(x[2])))# 传入索引的元组
df_temp.index = new_idx
df_temp.head()
BigCD
Smallcdcd
Othercatdogcatdogcatdogcatdog
UpperLowerExtra
AaALPHA36-9-6-6-209
BETA-5-33-8-3-258
bALPHA-44-107-466
BETA-99-685-2-9-8
BaALPHA0-91-629-7-9

3.索引的设置与重置

df_new = pd.DataFrame({'A':list('aabb'),
                      'B':list('PQRT'),
                      'C':[1,2,3,4]})
df_new
ABC
0aP1
1aQ2
2bR3
3bT4
df_new.set_index(['A'],append=True)# 通过append参数代表是否保留原索引
#指定多个列当做索引就传列表
BC
A
0aP1
1aQ2
2bR3
3bT4
# 上面是将原有的列当做索引;若新添加索引,可以先加Series,然后同上
my_index = pd.Series(list('WXYZ'), name='D')
df_new = df_new.set_index(['A',my_index])
df_new
BC
AD
aWP1
XQ2
bYR3
ZT4
# reset_index是其逆过程,传的是列表,将索引返回到列,如果drop=True就丢掉
df_new.reset_index(['D'],drop=True) 
BC
A
aP1
aQ2
bR3
bT4
# 索引变形reindex
df_reindex = pd.DataFrame({"Weight":[60,70,80],
                            "Height":[176,180,179]},
                             index=['1001','1003','1002'])
df_reindex
WeightHeight
100160176
100370180
100280179
df_reindex.reindex(index=['1001','1002','1003','1004'],
                  columns=['Weight','Gender'])
WeightGender
100160.0NaN
100280.0NaN
100370.0NaN
1004NaNNaN
# 索引运算
df_set_1 = pd.DataFrame([[0,1],[1,2],[3,4]],
                        index = pd.Index(['a','b','a'],name='id1'))
df_set_2 = pd.DataFrame([[4,5],[2,6],[7,1]],
                        index = pd.Index(['b','b','c'],name='id2'))
df_set_in_col_1 = df_set_1.reset_index()
df_set_in_col_2 = df_set_2.reset_index()
# df_set_in_col_1[[False,True,False]] 
df_set_in_col_1[df_set_in_col_1.id1.isin(df_set_in_col_2.id2)]
id101
1b12

练习

Ex1:公司员工数据集

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

# loc
df_demo = df.loc[(df.age <= 40) & (df.gender == 'M') & df.department.isin(['Dairy', 'Bakery'])]
print(df_demo.head())

用loc方法直接将几个条件连接起来就得到了。

# query
df_demo = df.query('((age <= 40) & (gender == \'M\') & department in([\'Dairy\', \'Bakery\']))')# 'numpy.ndarray'
print(df_demo.head()) # 这里用in,而不能用方法isin,这个方法是Series的。因为其省略了df的书写,如果是df.department时可以,但报错显示是数组。

用query方法可以省略对于df的书写。我第一次时仍然像loc一样使用isin,但发现报错,所以在字符串内应该使用in。
参考答案的方法如下:

dpt = ['Dairy', 'Bakery']
df.query("(age <= 40)&(department == @dpt)&(gender=='M')").head(3)  # @代表引入外面的变量。忘了

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

df_demo = df.iloc[(df.EmployeeID.values % 2 != 0), [0, 2, -2]]
print(df_demo)

通过题意,看出选择iloc比较合适。因为关心的是第几列,而不是某列的值。参考答案的方法也是这样的:

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

答案是先得到布尔的df,然后求values得到列表;我先求values得到列表,然后对列表求布尔。

3.按照以下步骤进行索引操作:
a.把后三列设为索引后交换内外两层

df_demo = df.set_index(['department', 'job_title', 'gender']).swaplevel(0, 2, axis=0)# 这里0代表行
# 参考答案
df_demo = df.set_index(df.columns[-3:].tolist()).swaplevel(0, 2, axis=0)

这里要选择后三列,先通过列索引得到然后将其转化为列表型。(我一开始想到了通过列索引得到后三列,但忘了tolist这一步,否则是Series不是列表。
b.恢复中间一层

df_demo = df_demo.reset_index(['job_title'])
# 参考答案
df_demo = df_demo.reset_index(level=1)# 这里直接设置level为1就行。原来reset_index也可以这样用

c.修改外层索引名为 Gender

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

d.用下划线合并两层行索引

# 一开始想到的是reindex索引变形,并不正确
# df_demo = df_demo.reindex(index=['Gender','department'])

# 利用map实现多级压缩,map是index的方法
df_temp = df_demo.copy()
new_index = df_temp.index.map(lambda x: (x[0]+'_'+x[1]))    # '_'.join(x)将列表x用_连接为字符串
df_temp.index = new_index

e.把行索引拆分为原状态

re_index = df_temp.index.map(lambda x: tuple(x.split('_')))
df_temp.index = re_index    # 展开后名字没了啊

这里展开之后索引没名字了(怪不得下面还有两问)
f.修改索引名为原表名称


df_temp = df_temp.reindex_like(df_demo) # 因为temp是从demo copy来的,所以直接like demo即可呀。但是后面恢复时gender变NaN了。
# 参考答案
df_temp = df_temp.rename_axis(index=['gender', 'department'])

还是答案正确
g.恢复默认索引并将列保持为原表的相对位置

df_temp = df_temp.reset_index() # reset后如何保持原表相对位置。
df_temp = df_temp.reorder_levels([3, 4, 5, 6, 0, 1, 2], axis=1) # 1代表列
# 一开始想到的是索引层的交换(看了教程想起来的)。看报错发现不对,这是针对多层索引内交换。
# 参考答案
df_temp = df_temp.reset_index().reindex(df.columns,  axis=1)

总结

这次学习任务感觉索引的方法很多。就算看过并敲过一遍,然后在题目需要用到的时候还是想不到。还是不熟练的原因吧,还需多加练习,学习的路还很长。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值