索引操作
pandas数据的索引就像一本书的目录,让我们可以很快地找到想要看的章节,对于大量数据,创建合理的具有业务意义的索引对我们分析数据至关重要。
对索引的操作是DataFrame最基础的操作。为了满足业务的各种需求,索引对象支持数字、类别、时间日期、周期、时差等多个类型,Pandas也提供了丰富的索引操作功能。
- 行索引是数据的索引,列索引指向的事一个Series;
- DataFrame的索引也是系列形成的Series的索引;
- 建立索引让数据更加直观明确,每行数据是针对哪个主题的;
- 建立索引方便数据处理;
- 索引允许重复,但业务上一般不会让它重复。
- 有时一个行或列层级较多的数据会出现多层索引的情况。
指定哪一列作为索引
在读取数据时,就可以通过Index_col=’类标签’来指定哪一列作为索引,
如果加载时没有指定索引,可以使用df.set_index(‘列标签’)来指定哪一行作为索引
如有必要,甚至可以设置2层索引:df.set_index([‘列标签1′,’列标签2’])
df.set_index(['name', 'team'],inplace=True) # 设置两层索引# 将列标签的第一个字符和另一个列标签设置为索引df.set_index([df.列标签.str[0],'列标签'],inplace=True)df.set_index(['name', 'team'],inplace=True) # 设置两层索引 # 将列标签的第一个字符和另一个列标签设置为索引 df.set_index([df.列标签.str[0],'列标签'],inplace=True)
inplace=True表示直接对原数据表进行修改,inplace=False表示不对原数据表进行修改,但是返回一个修改后的结果,可以赋值给其他变量
将某一列指定为索引后,那么它就会移动位置到第一列以索引的方式呈现,但是也有方法将它们设为索引的同时,还保留在原来的位置,也就是设置drop=False:
df.set_index(‘列标签’, drop=False) # 保留原列
如果将某一列指定为索引,原来的索引就会被移除,设置append=True,会修改索引并且保留原来的索引:
df.set_index(‘列标签’, append=True) # 保留原来的索引
可以将一个Series指定为索引:
df=pd.read_csv('1.csv')#生成1个Series,长度必须要与数据表的行数相匹配,# range是从0开始计数的,如果参数是X,生成的序列是从0到X-1s=pd.Series([i for i in range(6)]) #数据表不算表头的内容部分有6行就填6df.set_index(s,inplace=True)print(df)#Series可以进行运算df.set_index([s,s**2],inplace=True)df=pd.read_csv('1.csv') #生成1个Series,长度必须要与数据表的行数相匹配, # range是从0开始计数的,如果参数是X,生成的序列是从0到X-1 s=pd.Series([i for i in range(6)]) #数据表不算表头的内容部分有6行就填6 df.set_index(s,inplace=True) print(df) #Series可以进行运算 df.set_index([s,s**2],inplace=True)
重置索引
如果想要取消已有的索引,可以使用df.reset_index(),它的操作与set_index相反
df.reset_index() # 清除索引df.set_index('列标签').reset_index() # 相当于什么也没做# 删除原索引,month列没了df.set_index('列标签').reset_index(drop=True)df2.reset_index(inplace=True) # 覆盖使生效#level参数的意思应该是,在有多个索引的情况下,删除哪个索引,可以按索引的索引删除,也可以按索引的列标签删除df.set_index(['列标签1', '列标签2']).reset_index(level=1)df2.reset_index(level='列标签') # 同上,使用层级索引名df.reset_index(level='列标签', col_level=1) # 列索引# 不存在层级名称的填入指定名称df.reset_index(level='列标签', col_level=1, col_fill='species')df.reset_index() # 清除索引 df.set_index('列标签').reset_index() # 相当于什么也没做 # 删除原索引,month列没了 df.set_index('列标签').reset_index(drop=True) df2.reset_index(inplace=True) # 覆盖使生效 #level参数的意思应该是,在有多个索引的情况下,删除哪个索引,可以按索引的索引删除,也可以按索引的列标签删除 df.set_index(['列标签1', '列标签2']).reset_index(level=1) df2.reset_index(level='列标签') # 同上,使用层级索引名 df.reset_index(level='列标签', col_level=1) # 列索引 # 不存在层级名称的填入指定名称 df.reset_index(level='列标签', col_level=1, col_fill='species')
索引的操作
以下是索引的常用操作,这些操作会在我们今后处理数据中发挥作用。以下方法也适用于df.columns,因为都是index对象。
有些是对原数据表进行修改,有些是返回一个想要的值,
如果要对原数据表进行修改,可能要用到inplace=True
# 常用方法df.index.astype('int64') # 转换类型df.index.isin() # 是否存在,见下方示例df.index.rename('number') # 修改索引名称df.index.nunique() # 不重复值的数量df.index.sort_values(ascending=False,) # 排序,倒序df.index.map(lambda x:x+'_') # map函数处理df.index.str.replace('_', '') # str替换df.index.str.split('_') # 分隔df.index.to_list() # 转为列表df.index.to_frame(index=False, name='a') # 转成DataFramedf.index.to_series() # 转为seriesdf.index.to_numpy() # 转为numpydf.index.unique() # 去重df.index.value_counts() # 去重及计数df.index.where(df.index=='a') # 筛选df.index.rename('grade', inplace=False) # 重命名索引df.index.rename(['species', 'year']) # 多层,重命名索引df.index.max() # 最大值df.index.argmax() # 最大值的索引值df.index.any() #只要Index中有一个值可以表示为True,就返回Truedf.index.all() #是否全部可以表示为True?df.index.T # 转置,在多层索引里很有用# 常用方法 df.index.astype('int64') # 转换类型 df.index.isin() # 是否存在,见下方示例 df.index.rename('number') # 修改索引名称 df.index.nunique() # 不重复值的数量 df.index.sort_values(ascending=False,) # 排序,倒序 df.index.map(lambda x:x+'_') # map函数处理 df.index.str.replace('_', '') # str替换 df.index.str.split('_') # 分隔 df.index.to_list() # 转为列表 df.index.to_frame(index=False, name='a') # 转成DataFrame df.index.to_series() # 转为series df.index.to_numpy() # 转为numpy df.index.unique() # 去重 df.index.value_counts() # 去重及计数 df.index.where(df.index=='a') # 筛选 df.index.rename('grade', inplace=False) # 重命名索引 df.index.rename(['species', 'year']) # 多层,重命名索引 df.index.max() # 最大值 df.index.argmax() # 最大值的索引值 df.index.any() #只要Index中有一个值可以表示为True,就返回True df.index.all() #是否全部可以表示为True? df.index.T # 转置,在多层索引里很有用
以下是一些不常用但很重要的操作:
# 其他,不常用df.index.append(pd.Index([4,5])) # 追加df.index.repeat(2) # 重复几次df.index.inferred_type # 推测数据类型df.index.hasnans # 有没有空值df.index.is_monotonic_decreasing # 是否单调递减df.index.is_monotonic # 是否有单调性df.index.is_monotonic_increasing # 是否单调递增df.index.nbytes # 基础数据中的字节数df.index.ndim # 维度数,维数df.index.nlevels # 索引层级数,通常为1df.index.min() # 最小值df.index.argmin() # 最小索引值df.index.argsort() # 顺序值组成的数组df.index.asof(2) # 返回最近的索引# 索引类型转换df.index.astype('int64', copy=True) # 深拷贝# 拷贝df.index.copy(name='new', deep=True, dtype='int64')df.index.delete(1) # 删除指定位置# 对比不同df.index.difference(pd.Index([1,2,4]), sort=False)df.index.drop('a', errors='ignore') # 删除df.index.drop_duplicates(keep='first') # 去重值df.index.droplevel(0) # 删除层级df.index.dropna(how='all') # 删除空值df.index.duplicated(keep='first') # 重复值在结果数组中为Truedf.index.equals(df.index) # 与另一个索引对象是否相同df.index.factorize() # 分解成(array:0-n, Index)df.index.fillna(0, {0:'nan'}) # 填充空值# 字符列表,把name值加在第一位,每个值加10df.index.format(name=True, formatter=lambda x:x+10)# 返回一个array,指定值的索引位数组,不在的为-1df.index.get_indexer([2,9])# 获取指定层级Index对象df.index.get_level_values(0)# 指定索引的位置,见示例df.index.get_loc('b')df.index.insert(2, 'f') # 在索引位2插入fdf.index.intersection(df.index) # 交集df.index.is_(df.index) # 类似is检查df.index.is_categorical() # 是否分类数据df.index.is_type_compatible(df.index) # 类型是否兼容df.index.is_type_compatible(1) # 类型是否兼容df.index.isna() # array是否为空df.index.isnull() # array是否缺失值df.index.join(df.index, how='left') # 连接df.index.notna() # 是否不存在的值df.index.notnull() # 是否不存在的值df.index.ravel() # 展平值的ndarraydf.index.reindex(['a','b']) # 新索引 (Index,array:0-n)df.index.searchsorted('f') # 如果插入这个值,排序后在哪个索引位df.index.searchsorted([0, 4]) # array([0, 3]) 多个df.index.set_names('quarter') # 设置索引名称df.index.set_names('species', level=0)df.index.set_names(['kind', 'year'], inplace=True)df.index.shift(10, freq='D') # 日期索引向前移动10天idx1.symmetric_difference(idx2) # 两个索引不同的内容idx1.union(idx2) # 拼接df.add_prefix('t_') # 表头加前缀df.add_suffix('_d') # 表头加后缀df.first_valid_index() # 第一个有值的索引df.last_valid_index() # 最后一个有值的索引# 其他,不常用 df.index.append(pd.Index([4,5])) # 追加 df.index.repeat(2) # 重复几次 df.index.inferred_type # 推测数据类型 df.index.hasnans # 有没有空值 df.index.is_monotonic_decreasing # 是否单调递减 df.index.is_monotonic # 是否有单调性 df.index.is_monotonic_increasing # 是否单调递增 df.index.nbytes # 基础数据中的字节数 df.index.ndim # 维度数,维数 df.index.nlevels # 索引层级数,通常为1 df.index.min() # 最小值 df.index.argmin() # 最小索引值 df.index.argsort() # 顺序值组成的数组 df.index.asof(2) # 返回最近的索引 # 索引类型转换 df.index.astype('int64', copy=True) # 深拷贝 # 拷贝 df.index.copy(name='new', deep=True, dtype='int64') df.index.delete(1) # 删除指定位置 # 对比不同 df.index.difference(pd.Index([1,2,4]), sort=False) df.index.drop('a', errors='ignore') # 删除 df.index.drop_duplicates(keep='first') # 去重值 df.index.droplevel(0) # 删除层级 df.index.dropna(how='all') # 删除空值 df.index.duplicated(keep='first') # 重复值在结果数组中为True df.index.equals(df.index) # 与另一个索引对象是否相同 df.index.factorize() # 分解成(array:0-n, Index) df.index.fillna(0, {0:'nan'}) # 填充空值 # 字符列表,把name值加在第一位,每个值加10 df.index.format(name=True, formatter=lambda x:x+10) # 返回一个array,指定值的索引位数组,不在的为-1 df.index.get_indexer([2,9]) # 获取指定层级Index对象 df.index.get_level_values(0) # 指定索引的位置,见示例 df.index.get_loc('b') df.index.insert(2, 'f') # 在索引位2插入f df.index.intersection(df.index) # 交集 df.index.is_(df.index) # 类似is检查 df.index.is_categorical() # 是否分类数据 df.index.is_type_compatible(df.index) # 类型是否兼容 df.index.is_type_compatible(1) # 类型是否兼容 df.index.isna() # array是否为空 df.index.isnull() # array是否缺失值 df.index.join(df.index, how='left') # 连接 df.index.notna() # 是否不存在的值 df.index.notnull() # 是否不存在的值 df.index.ravel() # 展平值的ndarray df.index.reindex(['a','b']) # 新索引 (Index,array:0-n) df.index.searchsorted('f') # 如果插入这个值,排序后在哪个索引位 df.index.searchsorted([0, 4]) # array([0, 3]) 多个 df.index.set_names('quarter') # 设置索引名称 df.index.set_names('species', level=0) df.index.set_names(['kind', 'year'], inplace=True) df.index.shift(10, freq='D') # 日期索引向前移动10天 idx1.symmetric_difference(idx2) # 两个索引不同的内容 idx1.union(idx2) # 拼接 df.add_prefix('t_') # 表头加前缀 df.add_suffix('_d') # 表头加后缀 df.first_valid_index() # 第一个有值的索引 df.last_valid_index() # 最后一个有值的索引
索引重命名
将一个数据列置为索引后,就不能再像修改列名那样修改索引的名称了,需要使用.df.rename_axis()方法。
这个方法不仅可以修改索引名,还可以修改列名。
需要注意的是,这里修改的是索引名称,不是索引或者列名本身。
对原数据表进行修改,需要加上inplace=True
s.rename_axis("student_name") # 索引重命名df.rename_axis(["dow", "hr"]) # 多层索引修改索引名df.rename_axis('info', axis="columns") # 修改行索引名# 修改多层列索引名df.rename_axis(index={'a': 'A', 'b': 'B'})# 修改多层列索引名df.rename_axis(columns={'name': 's_name', 'b': 'B'})df.rename_axis(columns=str.upper) # 行索引名变大写s.rename_axis("student_name") # 索引重命名 df.rename_axis(["dow", "hr"]) # 多层索引修改索引名 df.rename_axis('info', axis="columns") # 修改行索引名 # 修改多层列索引名 df.rename_axis(index={'a': 'A', 'b': 'B'}) # 修改多层列索引名 df.rename_axis(columns={'name': 's_name', 'b': 'B'}) df.rename_axis(columns=str.upper) # 行索引名变大写
修改索引内容
用来修改行和列的索引名的主要函数时df.rename和df.set_axis。
df.rename可以给定一个字典,键对应原名称,值对应想要修改成什么名称。
还可以传入一个与原索引等长度序列进行覆盖修改,用一个函数处理原索引名
示例:
# 一一对应修改列索引df.rename(columns={"A": "a", "B": "c"})df.rename(str.lower, axis='columns') #将列标签这一行的字母转换成小写,大写是upper# 修改行索引df.rename(index={0: "x", 1: "y", 2: "z"})df.rename({1: 2, 2: 4}, axis='index')# 修改数据类型df.rename(index=str)# 重新修改索引replacements = {l1:l2 for l1, l2 in zip(list1, list2)}df.rename(replacements)# 列名加前缀df.rename(lambda x:'t_' + x, axis=1)# 利用iter()函数的next特性修改df.rename(lambda x, y=iter('abcdef'): next(y), axis=1)# 修改列名,用解包形式生成新旧字段字典df.rename(columns=dict(zip(df, list('abcd'))))# 一一对应修改列索引 df.rename(columns={"A": "a", "B": "c"}) df.rename(str.lower, axis='columns') #将列标签这一行的字母转换成小写,大写是upper # 修改行索引 df.rename(index={0: "x", 1: "y", 2: "z"}) df.rename({1: 2, 2: 4}, axis='index') # 修改数据类型 df.rename(index=str) # 重新修改索引 replacements = {l1:l2 for l1, l2 in zip(list1, list2)} df.rename(replacements) # 列名加前缀 df.rename(lambda x:'t_' + x, axis=1) # 利用iter()函数的next特性修改 df.rename(lambda x, y=iter('abcdef'): next(y), axis=1) # 修改列名,用解包形式生成新旧字段字典 df.rename(columns=dict(zip(df, list('abcd'))))
df.set_axis可以将所需的索引分配给给定的轴,通过分配类似列表或索引的方式来更改列标签或行标签的索引。
# 修改索引df.set_axis(['a', 'b', 'c'], axis='index')# 修改列名df.set_axis(list('abcd'), axis=1)# 使修改生效df.set_axis(['a', 'b'], axis='columns', inplace=True)# 传入索引内容df.set_axis(pd.Index(list('abcde')), axis=0)# 修改索引 df.set_axis(['a', 'b', 'c'], axis='index') # 修改列名 df.set_axis(list('abcd'), axis=1) # 使修改生效 df.set_axis(['a', 'b'], axis='columns', inplace=True) # 传入索引内容 df.set_axis(pd.Index(list('abcde')), axis=0)
1 thought on “pandas索引操作”