zoukankan      html  css  js  c++  java
  • Pandas学习笔记2——索引

    在这里插入图片描述
    Task02:索引(3天)

    单级索引

    loc方法、iloc方法、[]操作符

    最常用的索引方法可能就是这三类,其中iloc表示位置索引,loc表示标签索引,[]也具有很大的便利性,各有特点。总结成一句话就是,行用loc,列用[],位置用iloc。

    loc方法

    loc的适用条件:只有在index 或者column 为标签型索引的情况下.,只加一个参数时,只能进行 行 选择

    loc可以让你按照索引来进行行列选择,这里需要注意的是:所有在loc中使用的切片全部包含右端点!这是因为如果作为Pandas的使用者,那么肯定不太关心最后一个标签再往后一位是什么,但是如果是左闭右开,那么就很麻烦,先要知道再后面一列的名字是什么,非常不方便,因此Pandas中将loc设计为左右全闭。

    loc的逗号两边可以是单个元素、元素列表、布尔列表、函数,四选一。
    (1)单行索引

    df.loc[1103] # 提取出1103这一行
    

    (2)多行索引

    df.loc[[1102,2304]] # 提取出1102和2304这两行
    df.loc[1304:2103].head() # 左右全闭,这里不同于切片
    df.loc[2402::-1].head() # 这里-1表示逆序
    

    (3)单列索引

    df.loc[:,'Height'].head() # 取‘Height’这一列
    

    (4)多列索引

    df.loc[:,['Height','Math']].head() # 取'Height','Math'这两列
    df.loc[:,'Height':'Math'].head() # 多列连续索引(是闭区间)
    

    (5)联合索引

    df.loc[1102:2401:3,'Height':'Math'] # 每三行取一次
    

    (6)函数式索引
    所谓传入函数,就是换个方式传入列表或者标量。只不过当你怎么生成这个结果,里面的骚操作空间就很大了,远比单单直接把loc参数定死要灵活。

    df.loc[lambda x:x['Gender']=='M'].head() # 取‘Gender’为‘M’的行
    #loc中使用的函数,传入参数就是前面的df
    
    # 这里的例子表示,loc中能够传入函数,并且函数的输入值是整张表,输出为标量、切片、合法列表(元素出现在索引中)、合法索引
    def f(x):
        return [1101, 1103]
    df.loc[f] # 取出‘1101’、‘1103’这两行
    

    (7)布尔索引

    df.loc[df['Address'].isin(['street_7','street_4'])].head() 
    # 取出‘Address’一列是‘street_7’、‘street_4’的所有行
    
    # 传入布尔列表
    # i[-1]指的是街道编号
    # 功能同上
    df.loc[[
        True if i[-1] == '4' or i[-1] == '7' else False
        for i in df['Address'].values
    ]].head()
    

    注:本质上说,loc中能传入的只有布尔列表和索引子集构成的列表,只要把握这个原则就很容易理解上面那些操作

    iloc方法

    iloc的适用条件:只有在index 是整形的情况适用,也就是只适合位置型索引

    如果说loc是按照索引(index)的值来选取的话,那么iloc就是按照索引的位置来进行选取。iloc不关心索引的具体值是多少,只关心位置是多少,所以使用iloc时方括号中只能使用数值。

    注意与loc不同,切片右端点不包含

    (1)单行索引

    df.iloc[3] # 取第四行
    # 与下面的loc用法是一样的效果
    df.loc[1104] # ‘1104’是索引名
    

    (2)多行索引

    df.iloc[3:5]
    

    (3)单列索引

    df.iloc[:,3].head()
    

    (4)多列索引

    df.iloc[:, 7::-2].head()  # 倒序,且每两列取一次
    

    (5)混合索引

    df.iloc[3::4,7::-2].head() # 每四行取一行,每两列取一列(倒序)
    

    (6)函数式索引

    df.iloc[lambda x:[3]].head() # 取第四行
    

    注:iloc中接收的参数只能为整数或整数列表或布尔列表,不能使用布尔Series,如果要用就必须如下把values拿出来。

    #df.iloc[df['School']=='S_1'].head() #报错
    df.iloc[(df['School']=='S_1').values].head()
    

    [] 操作符

    Series的[]操作

    (1)单元素索引

    s = pd.Series(df['Math'],index=df.index)
    s[1101]
    #使用的是索引标签
    

    (2)多行索引

    s[0:4]
    #使用的是绝对位置的整数切片,与元素无关,这里容易混淆
    

    (3)函数式索引

    s[lambda x: x.index[16::-6]]
    #注意使用lambda函数时,直接切片(如:s[lambda x: 16::-6])就报错,此时使用的不是绝对位置切片,而是元素切片,非常易错
    

    (4)布尔索引

    s[s>80]
    

    注:如果不想陷入困境,请不要在行索引为浮点时使用[]操作符,因为在Series中[]的浮点切片并不是进行位置比较,而是值比较,非常特殊。
    在这里插入图片描述

    DataFrame的[]操作

    (1)单行索引

    df[1:2]
    #这里非常容易写成df['label'],会报错
    #同Series使用了绝对位置切片
    
    #如果想要获得某一个元素,可用如下get_loc方法:
    row = df.index.get_loc(1102)
    df[row:row+1]
    

    (2)多行索引

    #用切片,如果是选取指定的某几行,推荐使用loc,否则很可能报错
    df[3:5]
    

    (3)但列索引

    df['School'].head()
    

    (4)多列索引

    df[['School','Math']].head()
    

    (5)函数式索引

    df[lambda x:['Math','Physics']].head()
    

    (6)布尔索引

    df[df['Gender']=='F'].head()
    

    注:一般来说,[]操作符常用于列选择或布尔选择,尽量避免行的选择。

    布尔索引

    (1)布尔符号:’&’,’|’,’~’:分别代表和and,或or,取反not

    df[(df['Gender']=='F')&(df['Address']=='street_2')].head()
    # 取‘Gender’为‘F’,‘Address’为‘street_2’的所有行
    
    # 取‘Math’>85或者‘Address’为‘street_7’满足一项的所有行
    df[(df['Math']>85)|(df['Address']=='street_7')].head()
    
    # 取反
    df[~((df['Math']>75)|(df['Address']=='street_1'))].head()
    

    (2)loc和[]中相应位置都能使用布尔列表选择:

    df.loc[df['Math'] > 60, df.columns == 'Physics'].head()
    

    思考:为什么df.loc[df[‘Math’]>60,(df[:8][‘Address’]==‘street_6’).values].head()得到和上述结果一样?values能去掉吗?

    df.loc[df['Math']>60,(df[:8]['Address']=='street_6').values].head()
    

    答:8位布尔列表,只有最后一个是‘True’,因此也就和上面一样,把最后一列给选进来。
    (3)isin方法

    df[df['Address'].isin(['street_1', 'street_4'])
       & df['Physics'].isin(['A', 'A+'])]
    
    #上面也可以用字典方式写:
    df[df[['Address', 'Physics']].isin({
        'Address': ['street_1', 'street_4'],
        'Physics': ['A', 'A+']
    }).all(1)]
    #all与&的思路是类似的,其中的1代表按照跨列方向判断是否全为True
    

    上面也可以用字典方式写:

    df[df[['Address', 'Physics']].isin({
        'Address': ['street_1', 'street_4'],
        'Physics': ['A', 'A+']
    }).all(1)]
    #all与&的思路是类似的,其中的1代表按照跨列方向判断是否全为True
    

    快速标量索引

    当只需要取一个元素时,at和iat方法能够提供更快的实现:

    display(df.at[1101,'School'])
    display(df.loc[1101,'School'])
    display(df.iat[0,0])
    display(df.iloc[0,0])
    

    下面测试他们的时间:

    %timeit df.at[1101,'School']
    %timeit df.loc[1101,'School']
    %timeit df.iat[0,0]
    %timeit df.iloc[0,0]
    

    在这里插入图片描述

    区间索引

    (1)利用interval_range方法

    pd.interval_range(start=0,end=5)
    #closed参数可选'left''right''both''neither',默认左开右闭
    
    pd.interval_range(start=0,periods=8,freq=5)
    #periods参数控制区间个数,freq控制步长
    

    在这里插入图片描述
    (2)利用cut将数值列转为区间为元素的分类变量,例如统计数学成绩的区间情况:

    math_interval = pd.cut(df['Math'], bins=[0, 40, 60, 80, 100])
    #注意,如果没有类型转换,此时并不是区间类型,而是category类型
    math_interval.head()
    

    在这里插入图片描述
    (3)区间索引的选取

    df_i = df.join(math_interval,rsuffix='_interval')[['Math','Math_interval']]
                .reset_index().set_index('Math_interval')
    df_i.head()
    

    在这里插入图片描述

    df_i.loc[65].head()
    #包含该值就会被选中
    

    在这里插入图片描述

    df_i.loc[[65,90]]
    

    在这里插入图片描述
    如果想要选取某个区间,先要把分类变量转为区间变量,再使用overlap方法:

    #df_i.loc[pd.Interval(70,75)].head() 报错
    df_i[df_i.index.astype('interval').overlaps(pd.Interval(70, 85))].head()
    

    在这里插入图片描述

    多级索引

    创建多级索引

    通过from_tuple或from_arrays

    (1)直接创建元组

    tuples = [('A','a'),('A','b'),('B','a'),('B','b')]
    mul_index = pd.MultiIndex.from_tuples(tuples, names=('Upper', 'Lower'))
    mul_index
    
    pd.DataFrame({'Score':['perfect','good','fair','bad']},index=mul_index)
    

    在这里插入图片描述
    (2)利用zip创建元组

    L1 = list('AABB')
    L2 = list('abab')
    tuples = list(zip(L1,L2))
    mul_index = pd.MultiIndex.from_tuples(tuples, names=('Upper', 'Lower'))
    pd.DataFrame({'Score':['perfect','good','fair','bad']},index=mul_index)
    

    (3)通过Array创建元组

    arrays = [['A', 'a'], ['A', 'b'], ['B', 'a'], ['B', 'b']]
    mul_index = pd.MultiIndex.from_tuples(arrays, names=('Upper', 'Lower'))
    pd.DataFrame({'Score': ['perfect', 'good', 'fair', 'bad']}, index=mul_index)
    

    通过from_product

    L1 = ['A','B']
    L2 = ['a','b']
    mul_index = pd.MultiIndex.from_product([L1,L2],names=('Upper', 'Lower'))
    #两两相乘
    pd.DataFrame({'Score': ['perfect', 'good', 'fair', 'bad']}, index=mul_index)
    

    指定df中的列创建(set_index方法)

    df_using_mul = df.set_index(['Class','Address'])
    df_using_mul.head()
    

    多层索引切片

    (1)一般切片

    #df_using_mul.loc['C_2','street_5']
    #当索引不排序时,单个索引会报出性能警告
    #df_using_mul.index.is_lexsorted()
    #该函数检查是否排序
    df_using_mul.sort_index().loc['C_2','street_5']
    #df_using_mul.sort_index().index.is_lexsorted()
    
    #df_using_mul.loc[('C_2','street_5'):] 报错
    #当不排序时,不能使用多层切片
    df_using_mul.sort_index().loc[('C_2','street_6'):('C_3','street_4')]
    #注意此处由于使用了loc,因此仍然包含右端点
    
    df_using_mul.sort_index().loc[('C_2','street_7'):'C_3'].head()
    #非元组也是合法的,表示选中该层所有元素
    

    (2)第一类特殊情况:由元组构成列表

    df_using_mul.sort_index().loc[[('C_2','street_7'),('C_3','street_2')]]
    #表示选出某几个元素,精确到最内层索引
    

    (3)第二类特殊情况:由列表构成元组

    df_using_mul.sort_index().loc[(['C_2','C_3'],['street_4','street_7']),:]
    #选出第一层在‘C_2’和'C_3'中且第二层在'street_4'和'street_7'中的行
    

    注意两者的区别:
    在这里插入图片描述

    多层索引中的slice对象

    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_s = pd.DataFrame(np.random.rand(9,9),index=mul_index1,columns=mul_index2)
    df_s
    

    索引Slice的使用非常灵活:

    df_s.loc[idx['B':,df_s['D']['d']>0.3],idx[df_s.sum()>4]]
    #df_s.sum()默认为对列求和,因此返回一个长度为9的数值列表
    

    索引层的交换

    swaplevel方法(两层交换)

    df_using_mul.swaplevel(i=1,j=0,axis=0).sort_index().head()
    

    在这里插入图片描述

    #如果索引有name,可以直接使用name
    df_muls.reorder_levels(['Address','School','Class'],axis=0).sort_index().head()
    

    效果是一样的。

    索引设定

    index_col参数

    index_col是read_csv中的一个参数,而不是某一个方法:

    pd.read_csv('data/table.csv',index_col=['Address','School']).head()
    

    在这里插入图片描述

    reindex和reindex_like

    (1)reindex是指重新索引,它的重要特性在于索引对齐,很多时候用于重新排序

    df.reindex(index=[1101,1203,1206,2402])
    
    df.reindex(columns=['Height','Gender','Average']).head()
    

    在这里插入图片描述
    (2)可以选择缺失值的填充方法:fill_value和method(bfill/ffill/nearest),其中method参数必须索引单调

    df.reindex(index=[1101,1203,1206,2402],method='bfill')
    #bfill表示用所在索引1206的后一个有效行填充,ffill为前一个有效行,nearest是指最近的
    
    df.reindex(index=[1101,1203,1206,2402],method='nearest')
    #数值上1205比1301更接近1206,因此用前者填充
    

    (3)reindex_like的作用为生成一个横纵索引完全与参数列表一致的DataFrame,数据使用被调用的表

    df_temp = pd.DataFrame({
        'Weight': np.zeros(5),
        'Height': np.zeros(5),
        'ID': [1101, 1104, 1103, 1106, 1102]
    }).set_index('ID')
    df_temp.reindex_like(df[0:5][['Weight', 'Height']])
    

    (4)如果df_temp单调还可以使用method参数:

    df_temp = pd.DataFrame({
        'Weight': range(5),
        'Height': range(5),
        'ID': [1101, 1104, 1103, 1106, 1102]
    }).set_index('ID').sort_index()
    df_temp.reindex_like(df[0:5][['Weight', 'Height']], method='bfill')
    #可以自行检验这里的1105的值是否是由bfill规则填充
    

    set_index和reset_index

    (1)先介绍set_index:从字面意思看,就是将某些列作为索引。
    (2)使用表内列作为索引:

    df.set_index('Class').head()
    

    (3)利用append参数可以将当前索引维持不变

    df.set_index('Class',append=True).head()
    

    在这里插入图片描述
    (4)当使用与表长相同的列作为索引(需要先转化为Series,否则报错):

    df.set_index(pd.Series(range(df.shape[0]))).head()
    

    (5) 可以直接添加多级索引:

    df.set_index([pd.Series(range(df.shape[0])),
                  pd.Series(np.ones(df.shape[0]))]).head()
    

    (6)下面介绍reset_index方法,它的主要功能是将索引重置
    (7)默认状态直接恢复到自然数索引:
    在这里插入图片描述
    (8)用level参数指定哪一层被reset,用col_level参数指定set到哪一层:
    在这里插入图片描述

    rename_axis和rename

    (1)rename_axis是针对多级索引的方法,作用是修改某一层的索引名,而不是索引标签

    df_temp.rename_axis(index={'Lower':'LowerLower'},columns={'Big':'BigBig'})
    

    (2)rename方法用于修改列或者行索引标签,而不是索引名:

    df_temp.rename(index={'A':'T'},columns={'e':'changed_e'}).head()
    

    常用索引型函数

    where函数

    (1)对条件为False的单元进行填充
    在这里插入图片描述
    (2)通过这种方法筛选结果和[]操作符的结果完全一致:

    # 把‘Gender’不等于M的行全部去除
    df.where(df['Gender']=='M').dropna().head()
    

    (3)第一个参数为布尔条件,第二个参数为填充值:

    df.where(df['Gender']=='M',np.random.rand(df.shape[0],df.shape[1])).head()
    

    mask函数

    mask函数与where功能上相反,其余完全一致,即对条件为True的单元进行填充

    # 把‘Gender’等于M的所有行全部删除
    df.mask(df['Gender']=='M').dropna().head()
    
    df.mask(df['Gender']=='M',np.random.rand(df.shape[0],df.shape[1])).head()
    

    query函数

    query函数中的布尔表达式中,下面的符号都是合法的:行列索引名、字符串、and/not/or/&/|/~/not in/in/==/!=、四则运算符

    df.query(
        '(Address in ["street_6","street_7"])&(Weight>(70+10))&(ID in [1303,2304,2402])'
    )
    

    重复元素处理

    duplicated方法

    (1)该方法返回了是否重复的布尔列表
    在这里插入图片描述
    (2)可选参数keep默认为first,即首次出现设为不重复,若为last,则最后一次设为不重复,若为False,则所有重复项为True

    drop_duplicates方法

    (1)从名字上看出为剔除重复项,这在后面章节中的分组操作中可能是有用的,例如需要保留每组的第一个值:

    df.drop_duplicates('Class')
    

    (2)参数与duplicate函数类似:

    df.drop_duplicates('Class',keep='last')
    

    (3)在传入多列时等价于将多列共同视作一个多级索引,比较重复项:

    df.drop_duplicates(['School','Class'])
    

    抽样函数

    这里的抽样函数指的就是sample函数
    (1)n为样本量

    df.sample(n=5)
    

    (2)frac为抽样比

    df.sample(frac=0.05)
    

    (3)replace为是否放回

    df.sample(n=df.shape[0],replace=True).head()
    

    (4)axis为抽样维度,默认为0,即抽行

    df.sample(n=3,axis=1).head()
    

    (5)weights为样本权重,自动归一化
    在这里插入图片描述

    参考内容

    1. 教程仓库链接
    2. 《利用Python进行数据分析》
  • 相关阅读:
    微信 token ticket jsapi_ticket access_token 获取 getAccessToken get_jsapi_ticket方法
    PHP 日志 记录 函数 支持 数组 对象 新浪 sae 环境 去掉 空格 换行 格式化 输出 数组转字符串
    原生 原始 PHP连接MySQL 代码 参考mysqli pdo
    PHP 数字金额转换成中文大写金额的函数 数字转中文
    使用PHPMailer发送带附件并支持HTML内容的邮件
    设置输出编码格式 header 重定向 执行时间 set_time_limit 错误 报告 级别 error_reporting
    html5 bootstrap pannel table 协议 公告 声明 文书 模板
    指向指针的指针
    二级指针
    c语言:当指针成为参数后
  • 原文地址:https://www.cnblogs.com/Jack-Tim-TYJ/p/12831898.html
Copyright © 2011-2022 走看看