zoukankan      html  css  js  c++  java
  • pandas之数据运算

    python科学计算的基本方式:

    向量化运算(矢量化运算),并行计算,摒弃了循环遍历(标量运算),浪费内存
    衡量一个人会不会用pandas做数据分析

    1. 会不会做聚合推导透视表,交叉表
    2. 会不会矢量化编程完成项目

    自定义运算
    apply():Series和DataFrame通用自定义运算函数(计算行/列)
    map():Series用
    applymap():DataFrame用计算单元格
    如果pandas库自带的运算和函数不满足需求,可以自定义函数,并同时将函数应用到pandas的每行/列或值上
    应用函数主要用于替代传统的for循环
    可以将map和apply的参数x理解为for循环的i值(series就是单值,DataFrame就是每一行/列)
    针对Series的map函数,会将自定义函数应用到Series对象的每个值

    不直接用于单元格的算法
    关于行列的思路,分割成每个单元格作比较

    参数传递

    • apply(top, n=1, column='math')  在apply函数内定义参数,帮助传入top内  def top(aa,n,columns='english')

    axis=0按行操作,默认  

    • 给这一列的所有行,进行运算

    axis=1按列操作

    • 给这一行的所有列,进行运算
    a = pd.Series([9,7,8,6],['a','b','c','d'])
    b = pd.DataFrame(np.arange(20).reshape(4,5),index=['a','b','c','d'])
    
    def ccc(x):
        return x.min()
    b.apply(ccc, axis=0)   #给这一列的所有行,进行运算,所以结果和想的不一样
    
    # 自定义函数的参数x,用apply调用,在运算过程中标识DataFrame的1行或者1列(是series对象,可以理解为for循环遍历,但是并行运算)
    def bbb(x):
        return pd.Series([x.min(),x.max()],index=['min','max'])  #构建Series返回,结果就是返回DataFrame
    b.apply(bbb)
    

     

    基本统计函数
    pandas的统计运算方法和numpy基本一致
    默认针对0轴(行)做运算,大部分函数可加参数axis-1改为列运算

    1. describe() 针对0轴的统计汇总,计数/平均值/标准差/最小值/四分位数/最大值,非数值型列,不计入(字符串)指标
    2. sum()计算数据的总和,按针对0轴计算(各行计算),针对1轴计算参数改为1
    3. count() 非nan值数量
    4. mean()/median()/mode() 计算数据的算数平均值/中位数/众数
    5. var()/std() 计算数据的方差/标准差
    6. min()/max() 计算数据的最大值/最小值
    7. idxmin()/idxmax() 计算数据的第一个最大值/最小值所在的位置索引,给索引切片使用(自定义索引,排除null/na等空值)

     

    pandas分组聚合-基础
    数据分析阶段
    数据规律(清洗阶段后),下一个阶段就是分组聚合,分组聚合只针对数值类型

    • 对数据集分组并对各组应用一个函数是数据分析中的重要环境
    • 一般将数据准备好后,首先就是计算分组统计
    • sql能够方便的连接,过滤。转换和聚合数据,但sql能执行的分组运算种类优先,pandas则强大灵活很多

    聚合操作,一般是指应用某种方法(自定义的聚合函数或者系统自带的pandas的统计方法等)给数据降维

    聚合函数常用

    •  平均值:mean() 透视表
    •  个数:size() 交叉表、

    分组的作为行索引,聚合作为值(series),聚合作为列索引(DataFrame)

    数据分组
    分组聚合:groupby(),一般指以下一个或者多个操作步骤的集合
    splitting 分组:将列分割为n组
    applying 应用:将每个分组应用聚合函数
    combining合并:合并分组和聚合的结果
    name,score                       name ,score                  name ,score
    a    1                            a     1,2                     a    2
    a    2       ====>                b     3,4         ===>        b    4
    b    3       group by name                         max(score)
    b    4
    

    以单列基准分组,聚合其他

    a_values = [{"name": "锺洋","chinese": 23,"math": 25,"english": 25,"test": "一"
    },{"name": "李敏","chinese": 99,"math": 48,"english": 78,"test": "一"
    },{"name": "夏军","chinese": 70,"math": 83,"english": 12,"test": "一"
    },{"name": "姚明","chinese": 65,"math": 12,"english": 73,"test": '二'
    },{"name": "夏军","chinese": 80,"math": 63,"english": 45,"test": '二'
    },{"name": "夏军","chinese": 90,"math": 82,"english": 65,"test": '三'
    },{"name": "李帅","chinese": 99,"math": 58,"english": 78,"test": "一"}]
    df = pd.DataFrame(a_values)
    
    # 每位同学每课成绩的平均分
    # 分组
    x = df.groupby('name').mean()
    # 每位同学考试的次数
    y = df.groupby('name').size()
    # 将分组传递给变量
    class_group = df.groupby('name')
    class_group.size()
    # 如果不想使用分组作为列索引,设置参数as_index=False
    x = df.groupby('name',as_index=False).mean()

    以多列为基准

    • 多列分组
    • 单列或多列聚合
    # 单列多列分组
    df.groupby('name').mean()
    df.groupby(['name','test']).mean()
    

    多列单列聚合

    • 对于大数据集,很可能值需要对部分进行聚合
    • 下面三种写法结果一样
    • 分组聚合参数,传入标量形式得单个列名,返回Series
    • 分组聚合参数,传入列表或数组,返回DataFrame(默认传入所以列)
    # 对除分组基准列以外得所有列进行聚合
    df.groupby('name').sum()   # 多列聚合, 聚合除分组以外得所有列
    # 分组后,只对chinese单列聚合
    df['chinese'].groupby(df['name']).sum()   # 效率高,但是写法诡异
    df.groupby('name')['chinese'].sum()       # 书写简单,效率高,推荐,返回Series
    df.groupby('name')[['chinese']].sum()       # 书写简单,效率高,推荐,返回DataFrame
    
    # 分组后,多列聚合
    df.groupby('name')['chinese'].sum()       # 书写简单,效率高,推荐
    

    分组聚合进阶

    本质上 groupby传入得数据并不是行索引或列索引,而是任意一个和数据结构对应得序列(布尔,列表,数组,字典,Series)

    • 根据列表做分组基准
    • 根据字典或者Series做分组基准
    • 根据函数做分组基准
    • 根据层次化索引得级别做分组基准
    # 根据列表分组,列表值得个数必须和表格行或列数对应
    df.groupby('name').size()   #分组参数是列索引,直接获取某列得值
    df.groupby(df['name']).size() #手动将列值传入分组参数
    ###
    df_list = ['aa','bb','cc','dd','ee','ff','gg']  # 自定义列表作为分组基准
    df.groupby(df_list).size()
    #set_index把其中一列作为行索引 
    mapping = {'李敏':'one','姚明':'two'}
    df2 = df.set_index('name')
    df2.groupby(mapping).sum()
    # 使用seies进行分组
    df2.groupby(pd.Series(mapping)).size()
    

    通过函数分组

    • 比起字典或者series,函数是一种更原生得方法定义分组映射
    • 任何被当作分组键得函数都会在各个索引值上被调用一次,其返回值就会被作用分组基准

      

    people = pd.DataFrame(
        np.random.randn(5,5),
        columns=['a','bc','c','d','e'],
        index=['Joe','Steve','wes','jim','travis']
    )
    people.iloc[2:3,[1,2]] = np.nan
    
    # len把行索引字符得个数作为分组基准
    people.groupby(len).sum()
    # 
    a = [3,5,3,3,6]
    people.groupby(a).sum()
    #
    ccc = ['one','one','one','two','two']
    people.groupby([len,ccc]).sum()   #joe wes既有3个字符,又属于one ,针对行索引做的分组
    
    #使用函数分组
    people.groupby(len,axis=1).sum()
    #
    zzz  = ['one','one','one','two','two']
    people.groupby([len,zzz],axis=1).sum()
    

    # lianxi,输出每个学生在每次考次数中得数学平均分
    从一个原始大表中抽取一个符合需求得小标

    df.groupby(['name','test']).mean()   # 3维度
    df.groupby(['name','test'])['math'].mean()   #2维Series
    pd.DataFrame(df.groupby(['name','test'])['math'].mean() )
    df.groupby(['name','test'])['math'].mean().unstack().fillna(0).astype(np.int)  #2维series转换DataFrame
    
    df.groupby(['name','test'])['math'].mean().unstack().fillna(0).astype(np.int)  #2维series转换DataFrame
    # 称之为透视表
    抽出1列,分组后作为行索引
    抽出1列,分组后作为列索引
    抽出1列,平均值聚合后作为值
    

      

     

    根据层次化索引得级别分组
    要根据层次化索引得级别,使用level关键字传递级别序号或名字

    colums = pd.MultiIndex.from_arrays([['US','US','US','JP','JP',],[1,3,5,1,3]],names=['city','tenor'])
    hier_df = pd.DataFrame(np.random.randn(4,5),columns=colums)
    hier_df.groupby(level='city',axis=1).sum()   #默认按照行分组
    # 按行分组,自定义布尔数组做分组基准
    ddd = [True,True,False,False,False,False,True]
    df.groupby(ddd).sum()
    # 按照列分组
    ddd = [True,True,False,False,False]
    df.groupby(ddd,axis=1).sum()
    # 按列分组,自定义布尔数组做分组基准
    df.groupby(df.dtypes,axis=1).sum()
    
    #假设以知列得分组关系后,并希望根据分组计算列得和
    mapping={'a':'red','bc':'red','c':'bule','d':'bule','e':'red','f':'orange' } # 多写或少写不会执行,多了一个f,不会影响分组
    people.groupby(mapping,axis=1).sum()
    

     

    本文为原创文章,转载请标明出处
  • 相关阅读:
    js
    原型、原型链、闭包、继承
    js6.22
    js
    js
    在浏览器窗口上添加一个遮罩层
    git使用笔记
    前端开发面试题
    Web Worker
    js实现图片预加载
  • 原文地址:https://www.cnblogs.com/harden13/p/13037269.html
Copyright © 2011-2022 走看看