在Python Pandas的数据处理中,set_index是一个非常常用的函数,它的作用就是将DataFrame中的一列或多列作为新的索引。使用set_index函数,可以快速地进行数据的筛选和重组。
如何在pandas中使用set_index( )与reset_index( )设置索引
函数解释
set_index(keys, drop=False, append=True, inplace=True, verify_integrity=True).rename(columns={‘id’: ‘index_id’})
set_index的使用方法
set_index方法有两种使用方式:
import pandas as pd
df = pd.DataFrame(data={"姓名":['甲','乙','丙','丁'],"年龄":[12,23,34,43], "性别":['男','男','男','男']})
print(df) #构建表格格式
df2 = df.set_index('姓名') #将姓名那一列作为索引
print(df2)
df3 = df.set_index(['姓名','性别']) #将姓名和性别作为索引
print(df3)
结果:
姓名 年龄 性别
0 甲 12 男
1 乙 23 男
2 丙 34 男
3 丁 43 男
年龄 性别
姓名
甲 12 男
乙 23 男
丙 34 男
丁 43 男
年龄
姓名 性别
甲 男 12
乙 男 23
丙 男 34
丁 男 43
set_index的注意事项
在使用set_index时,需要注意以下几个事项:
Python数据处理工具 ——Pandas(数据的预处理)
通常,在Pandas模块中实现数据框子集的获取可以使用iloc、loc和ix三种“方法”,这三种方法既可以对数据行进行筛选,也可以实现变量的挑选,它们的语法可以表示成[rows_select,cols_select]。
iloc只能通过行号和列号进行数据的筛选,读者可以将iloc中的“i”理解为“integer”,即只能向[rows_select, cols_select]指定整数列表。该索引方式与数组的索引方式类似,都是从0开始,可以间隔取号,对于切片仍然无法取到上限。
loc要比iloc灵活一些,读者可以将loc中的“l”理解为“label”,即可以向[rows_select, cols_select]指定具体的行标签(行名称)和列标签(字段名)。注意,这里是标签不再是索引。而且,还可以将rows_select指定为具体的筛选条件,在iloc中是无法做到的。
ix是iloc和loc的混合,读者可以将ix理解为“mix”,该“方法”吸收了iloc和loc的优点,使数据框子集的获取更加灵活。为了使读者理解这三种方法的使用和差异,接下来通过具体的代码加以说明:
# 数据子集的获取
# 构造数据集
import pandas as pd
df1 = pd.DataFrame({'name':['张三','李四','王二','丁一','李五'],
'gender':['男','女','女','女','男'],
'age':[23,26,22,25,27]}, columns = ['name','gender','age'])
print(df1)
# 取出数据集的中间三行(即所有女性),并且返回姓名和年龄两列
print(df1.iloc[1:4,[0,2]] )
print(df1.loc[1:3, ['name','age']])
print(df1.ix[1:3,[0,2]])
注意:ix方法已经过时了,建议使用前两个
结果:
name gender age
0 张三 男 23
1 李四 女 26
2 王二 女 22
3 丁一 女 25
4 李五 男 27
name age
1 李四 26
2 王二 22
3 丁一 25
name age
1 李四 26
2 王二 22
3 丁一 25
AttributeError: 'DataFrame' object has no attribute 'ix'
注意,这时的数据集是以员工姓名作为行名称,不再是之前的行号,对于目标数据的返回同样可以使用iloc、loc和ix三种方法。对于iloc来说,不管什么形式的数据集都可以使用,始终表示行索引,即取哪些行下标的观测;loc就不能使用数值表示行标签了,因为此时数据集的行标签是姓名,所以需要写入中间三行对应的姓名;通过ix方法,既可以用行索引(如代码所示)表示,也可以用行标签表示,可根据读者的喜好选择。由于并没有对数据集的变量做任何限制,所以cols_select用英文冒号表示,代表取出数据集的所有变量。
很显然,在实际的学习和工作中,观测行的筛选很少是通过写入具体的行索引或行标签,而是对某些列做条件筛选,进而获得目标数据。例如,在上面的df1数据集中,如何返回所有男性的姓名和年龄,代码如下:
# 使用筛选条件,取出所有男性的姓名和年龄
import pandas as pd
df1 = pd.DataFrame({'name':['张三','李四','王二','丁一','李五'],
'gender':['男','女','女','女','男'],
'age':[23,26,22,25,27]}, columns = ['name','gender','age'])
print(df1)
print(df1.loc[df1.gender == '男',['name','age']])
结果:
name gender age
0 张三 男 23
1 李四 女 26
2 王二 女 22
3 丁一 女 25
4 李五 男 27
name age
0 张三 23
4 李五 27
如果是基于条件的记录筛选,只能使用loc和ix两种方法。正如代码所示,对iloc方法的那行代码做注释,是因为iloc不允许使用条件筛选,这行代码是无法运行成功的。对变量名的筛选,loc必须指定具体的变量名,而ix既可以使用变量名,也可以使用字段的数值索引。
loc和iloc函数用法详解(Python)
综上所述,ix方法几乎可以实现所有情况中数据子集的获取,是iloc和loc两种方法的优点合成体,而且对于行号与行名称一致的数据集来说(如df1数据集),名称索引的优先级在位置索引之前(如本节第一段代码中的df1.ix[1:3,[0,2]])。
读者可以将loc中的“l”理解为“label”,即可以向[rows_select, cols_select]指定具体的行标签(行名称)和列标签(字段名)。注意,这里是标签不再是索引。
提取特定单个数据
import pandas as pd
df = pd.DataFrame(data={"姓名":['甲','乙','丙','丁'],"年龄":[12,23,34,43], "性别":['男','男','男','男']})
df2 = df.set_index('姓名') #将姓名那一列作为索引
print(df2)
# 要查乙的性别,根据索引‘乙’和列标签‘性别’来筛选
print('乙的性别是:', df2.loc['乙','性别'])
结果:
年龄 性别
姓名
甲 12 男
乙 23 男
丙 34 男
丁 43 男
乙的性别是: 男
提取多行数据
import pandas as pd
df = pd.DataFrame(data={"姓名":['甲','乙','丙','丁'],"年龄":[12,23,34,43], "性别":['男','男','男','男']})
df2 = df.set_index('姓名') #将姓名那一列作为索引
print(df2)
print(df2.loc[['乙','丁'],['年龄','性别']])
结果:
年龄 性别
姓名
甲 12 男
乙 23 男
丙 34 男
丁 43 男
年龄 性别
姓名
乙 23 男
丁 43 男
Pandas库:从入门到应用(二)–行列数据读写
逐行读取DataFrame数据以及修改对应数据
import pandas as pd
df = pd.DataFrame(data={"姓名":['甲','乙','丙','丁'],"年龄":[12,23,34,43], "性别":['男','男','男','男']})
print(df)
df2 = df.set_index('姓名') #将姓名那一列作为行标签
print(df2)
# 方法一
name_list = df['姓名'].tolist()
print(name_list)
for i in range(4):
if name_list[i] in ['甲', '丁']:
print(df2.loc[name_list[i],'性别'])
df2.loc[name_list[i],'性别'] = '女'
else:
pass
# # 方法2
# df2.loc[['甲', '丁'],'性别'] = '女'
# print(df2)
结果:
甲 12 男
乙 23 男
丙 34 男
丁 43 男
['甲', '乙', '丙', '丁']
男
男