• 数据分析核心包pandas


    一 pandas简介

    pandas是一个强大的Python数据分析的工具包, 是基于NumPy构建的
    pandas的主要功能

    • 具备对其功能的数据结构DateFrame Series
    • 集成时间序列功能
    • 提供丰富的数学运算和操作
    • 灵活处理缺失数据

    安装方法: pip install pandas
    引用方法:import pandas as pd

    二 pands的Series对象

    1 Series 一维数据对象

    Seriaes是一种类似于一位数组的对象, 由一组数据和一组与之相关的数据标签(索引)组成新的二维数组
    创建方式:

    pd.Series([4,7,-5,3])
    pd.Series([4,7,-5,3], index=['a', 'b', 'c', 'd'])
    pd.Series({'a':1, 'b':2})
    pd.Series(0, index=['a','b','c','d'])

    获取值数组和索引数据: values属性和index属性
    Series比较像列表(数组)和字典的结合体

    2 Series使用特性

    Series支持array的特性(下标):

    • 从ndarray创建Series:Series(arr)
    • 与标量运算: sr*2
    • 两个Series运算: sr1+sr2
    • 索引:sr[0], sr[[1,2,4]]
    • 切片:sr[0:2]
    • 通用函数:np.abs(sr)
    • 布尔值过滤: sr[sr>0]

    Series支持字典的特性(标签):

    • 从字典创建Series: Series(dic)
    • in运算: 'a' in sr
    • 键索引:sr['a'], sr[['a','b', 'd']]

    3 Series整数索引问题

    整数索引的pandas对象往往会使新手抓狂的地方
    例如:

    • sr = pd.Series(np.arange(4.))
    • sr[-1]

    如果索引是整数类型,则根据整数进行下标获取值时总是面向标签的。
    解决方法: loc属性(将索引解释为标签)和iloc属性(将索引解释为下标)
    如:sr2.loc[10] sr2.iloc[-1]

    4 Series数据对齐

    例:

    • sr1 = pd.Series([12,23,34], index=['c','a','d'])
    • sr2 = pd.Series([11,20,10], index=['d', 'c', 'a'])
    • sr1+sr2

    pandas在进行两个Series对象的运算时,会按索引进行对齐然后计算

    • a:33
    • c:32
    • d:45

    如何使用结果再索引'b'处的值为11, 在索引‘d’处的值为34?

    • 灵活的算术方法: add, sub, div, mul
    • sr1.add(sr2, fill_value=0)

    5 Series缺失值处理

    缺失数据:使用NaN(Not a Number) 来表示缺失数据。其值等于np.nan。内置的None值也会被当做NaN处理

    sr.isnull()       Nan返回True
    sr.notnull()      Nan但会False
    sr.dropna()       删除索引Nan
    sr.fillna(0)      填充所有的nan

     过滤缺失数据:sr.dropna() 活 sr[data.notnull()]

     填充缺失数据:fillna(0)

    三 Pandas之DataFrame-二维数据对象

    DataFrame是一个表格型的数据结构, 含有一组有序的列。DataFrame可以被看做是由Series组成的字典,并且共用一个索引

    创建方式:

    pd.DataFrame({'one':[1,2,3,4], 'two':[4,3,2,1]})
    pd.DataFrame({'one':pd.Series([1,2,3], index=['a','b','c']), 'two':pd.Series([1,2,3,4],index=['b','a','c','d'])})

    csv文件读取与写入:

    df.read_csv('filename.csv')
    df.to_csv()

    DataFrame常用的属性:

    index         获取索引 行索引
    T             转置  行变成列 列变成行
    columns       获取列索引
    values        获取值数组
    describe()    获取快速统计

     DataFrame索引和切片:

    索引:

      - df[col] df[[c1,c2]]  # 取列

      - df.loc[index]         # 取列

      - df.loc[index, col]  # 取元素

    切片

      - df[a:b]  # 切行

      - df.loc[:, a:b]  # 切列

    DataFrame是一个二维数据类型,所以有行索引和列索引。
    DataFrame同样可以通过标签和位置两种方法进行索引和切片。
    loc属性和iloc属性:

    • 使用方法: 逗号隔开,前面是行索引, 后面是列索引
    • 行/列索引部分可以是常规索引,切片,布尔索引,花式索引任意搭配

    示例:

    # 先取列再取行
    df['one']['a']
    # 推荐使用loc
    df.loc['a', 'one']
    # 查看一行数据
    dc.loc['a', :]

    DataFrame数据对齐与缺失数据:

    DataFrame对象在运算时, 同样会进行数据对齐, 其行索引和列索引分别对齐
    DataFrame处理缺失数据的相关方法:

    dropna(axis=0, where='any', ...)  # 当行所有都是Nan才删除dropna(how='any') 
    fillna()
    isnull()
    notnull()

    四 pandas其他常用方法

    常用函数

    mean(axis=0, skipna=False)           对列(行)求平均数
    sum(axis=1)                          对列(行)求和
    sort_index(axis, ..., ascending)     对列(行)索引排序
    sort_values(by,axis, ascending)      安某一列(行)的值排序
    reset_index(drop=true)          重新处理index NumPy的通用函数同样适用于pandas

    五 pandas-时间对象处理

    时间序列类型:

    • 时间戳:特定时刻
    • 固定时刻: 如2017年7月
    • 时间间隔:起始时间-结束时间

    Python标准库处理时间对象:datetime

    灵活处理时间对象: dateutil

    dateutil.parser.parse()

    成组处理时间对象:pandas

    pd.to_datetime()

    生成时间范围:date_range

    • start 开始时间
    • end 结束时间
    • periods 时间长度
    • freq 时间频率, 默认为'D', 可选H(our), W(eek), B(usiness), S(emi0)M(onth), (min)T(es), S(econd), A(year)
    pd.date_range('2010-01-01', '2010-5-1')

    pandas-时间序列:

    时间序列就是以时间对象为索引的Series或DataFrame
    datetime对象作为索引时是存储在DatetimeIndex对象中的。
    时间序列特殊功能:

    • 传入“年”或“年月”作为切边方式
    • 传入日期范围作为切片方式
    • 丰富的函数支持: resample(), truncate()

     六  pandas-文件处理

    数据文件常用格式: csv(以某间隔符分割数据)

    pandas读取文件: 从文件名,URL,文件对象中加载数据

    read_csv     默认分隔符为逗号
    read_table   默认分隔符为制表符

    read_csv, read_table函数主要参数:

    sep               指定分隔符,可用正则表达式如"s+"
    header=None       指定文件无列名
    name              指定列名
    index_col         指定某列为索引
    skip_row          指定跳过某些行
    na_values         指定某些字符串表示缺失值
    parse_dates       指定某些列是否被解析为日期,类型布尔值或列表

    pandas写入csv文件: to_csv函数:

    sep            指定文件分隔符
    na_rep         指定缺失值转换的字符串,默认为空字符串
    header=False   不输出列名一行
    index=False    不输出索引一列
    cols           指定输出的列,传入列表

     七 Pands实现数据清洗

    处理丢失数据

    有两种丢失数据:

    • None
    • np.nan(NaN)

    1. None

    None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。

    2. np.nan(NaN)

    np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。

    1) pandas中None与np.nan都视作np.nan

    创建dataframe

    import numpy as np
    import pandas as pd
    
    df = pd.DataFrame(data=np.random.randint(10, 50, size=(8,8)))
    df
    
        0    1    2    3    4    5    6    7
    0    29    36    36    30    43    17    20    33
    1    43    21    49    19    30    33    49    10
    2    11    44    13    45    20    10    29    35
    3    10    34    45    12    29    26    10    15
    4    11    11    49    15    48    26    49    36
    5    26    45    44    28    42    33    43    45
    6    29    46    42    30    45    15    29    24
    7    28    23    26    28    29    15    18    32

    将某些数组元素赋值为nan

    df.iloc[1,3] = None
    df.iloc[2,2] = None
    df.iloc[4,2] = None
    df.iloc[6,7] = np.nan
    df
    
    0    1    2    3    4    5    6    7
    0    29    36    36.0    30.0    43    17    20    33.0
    1    43    21    49.0    NaN    30    33    49    10.0
    2    11    44    NaN    45.0    20    10    29    35.0
    3    10    34    45.0    12.0    29    26    10    15.0
    4    11    11    NaN    15.0    48    26    49    36.0
    5    26    45    44.0    28.0    42    33    43    45.0
    6    29    46    42.0    30.0    45    15    29    NaN
    7    28    23    26.0    28.0    29    15    18    32.0

    2) pandas处理空值操作

    • isnull()
    • notnull()
    • dropna(): 过滤丢失数据 可以选择过滤的是行还是列(默认为行):axis中0表示行,1表示的列
    • fillna(): 填充丢失数据
    #创建DataFrame,给其中某些元素赋值为nan
    df.notnull().all(axis=1)
    df[df.notnull().all(axis=1)]
    
    
    0    1    2    3    4    5    6    7
    0    29    36    36.0    30.0    43    17    20    33.0
    3    10    34    45.0    12.0    29    26    10    15.0
    5    26    45    44.0    28.0    42    33    43    45.0
    7    28    23    26.0    28.0    29    15    18    32.0

    3 填充函数 Series/DataFrame

    fillna():value和method参数

    可以选择前向填充还是后向填充, method 控制填充的方式 bfill ffill

    df.fillna(method='ffill', axis=0)
    
        0    1    2    3    4    5    6    7
    0    29    36    36.0    30.0    43    17    20    33.0
    1    43    21    49.0    30.0    30    33    49    10.0
    2    11    44    49.0    45.0    20    10    29    35.0
    3    10    34    45.0    12.0    29    26    10    15.0
    4    11    11    45.0    15.0    48    26    49    36.0
    5    26    45    44.0    28.0    42    33    43    45.0
    6    29    46    42.0    30.0    45    15    29    45.0
    7    28    23    26.0    28.0    29    15    18    32.0
    # 检查哪些列存在空值 并对检查出的空值进行覆盖
    df.isnull().any(axis=0)
    df.fillna(method='ffill', axis=0, inplace=True)
    df
    
    0    1    2    3    4    5    6    7
    0    29    36    36.0    30.0    43    17    20    33.0
    1    43    21    49.0    30.0    30    33    49    10.0
    2    11    44    49.0    45.0    20    10    29    35.0
    3    10    34    45.0    12.0    29    26    10    15.0
    4    11    11    45.0    15.0    48    26    49    36.0
    5    26    45    44.0    28.0    42    33    43    45.0
    6    29    46    42.0    30.0    45    15    29    45.0
    7    28    23    26.0    28.0    29    15    18    32.0

    八 Pands的高级操作

    1、删除重复元素(数据清洗的一种方式)

    使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True

    - keep参数:指定保留哪一重复的行数据
    • 创建具有重复元素行的DataFrame
    import numpy as np
    import pandas as pd
    from pandas import Series,DataFrame
    #创建一个df
    df = DataFrame(data=np.random.randint(0, 100, size=(8,4)))
    df
    
    #手动将df的某几行设置成相同的内容
    df.iloc[2] = [66,66,66,66]
    df.iloc[4] = [66,66,66,66]
    df.iloc[7] = [66,66,66,66]
    
    # 使用duplicated查看所有重复元素行
    df.duplicated(keep='first')
    0    False
    1    False
    2    False
    3    False
    4     True
    5    False
    6    False
    7     True
    dtype: bool
    
    # 删除重复元素的行
    # 发生重复的行索引
    index = df.loc[df.duplicated(keep='last')].index
    df.drop(labels=index, axis=0)

    使用drop_duplicates()函数删除重复的行

    • drop_duplicates(keep='first/last'/False)
    df.drop_duplicates(keep="last")
    
        0    1    2    3
    0    65    41    7    32
    1    15    17    13    38
    3    95    96    53    79
    5    54    81    49    78
    6    13    58    0    26
    7    66    66    66    66

     2. 映射

    1) replace()函数:替换元素

    使用replace()函数,对values进行映射操作

    Series替换操作

    • 单值替换
      • 普通替换
      • 字典替换(推荐)
    • 多值替换
      • 列表替换
      • 字典替换(推荐)
    • 参数
      • to_replace:被替换的元素

    DataFrame替换操作

    • 单值替换
      • 普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
      • 按列指定单值替换: to_replace={列标签:替换值} value='value'
    • 多值替换
      • 列表替换: to_replace=[] value=[]

    字典替换(推荐) to_replace={to_replace:value,to_replace:value}

    # 单值替换
    df.replace(to_replace=66, value=666)
        0    1    2    3
    0    65    41    7    32
    1    15    17    13    38
    2    66    66    66    66
    3    95    96    53    79
    4    66    66    66    66
    5    54    81    49    78
    6    13    58    0    26
    7    66    66    66    66
    # 多值替换
    df.replace(to_replace=[66, 25], value=[63, 2255])
    
        0    1    2    3
    0    65    41    7    32
    1    15    17    13    38
    2    63    63    63    63
    3    95    96    53    79
    4    63    63    63    63
    5    54    81    49    78
    6    13    58    0    26
    7    63    63    63    63
    # key列索引,value要替换的值
    df.replace(to_replace={2:66}, value=666)
    
        0    1    2    3
    0    65    41    7    32
    1    15    17    13    38
    2    66    66    666    66
    3    95    96    53    79
    4    66    66    666    66
    5    54    81    49    78
    6    13    58    0    26
    7    66    66    666    66

    注意:DataFrame中,无法使用method和limit参数

    2) map()函数:新建一列 , map函数并不是df的方法,而是series的方法

    • map()可以映射新一列数据
    • map()中可以使用lambd表达式
    • map()中可以使用方法,可以是自定义的方法

      eg:map({to_replace:value})

    • 注意 map()中不能使用sum之类的函数,for循环
    # 新增一列:给df中,添加一列,该列的值为中文名对应的英文名
    dic = {
        'name':['jay', 'tom', 'jay'],
        'salary':[10000,15000,10000]
    }
    df = DataFrame(data=dic)
    df
    
        name     salary
    0    jay    10000
    1    tom    15000
    2    jay    10000
    # 定制一个映射关系表
    dic = {
        'jay':'周杰伦',
        'tom':'张三'
    }
    df['c_name'] = df['name'].map(dic)
    df
    
         name    salary    c_name
    0    jay    10000    周杰伦
    1    tom    15000    张三
    2    jay    10000    周杰伦

    #### map当做一种运算工具,至于执行何种运算,是由map函数的参数决定的(参数:lambda,函数)
    - 使用自定义函数

    #超过10000部分的钱缴纳50%的税
    def after_sal(s):
        if s < 10000:
            return s
        else:
            return s-(s-10000)*0.5
    df['after_sal']=df['salary'].map(after_sal)
    df
    
        name salary    c_name    after_sal
    0    jay    10000    周杰伦    10000.0
    1    tom    15000    张三      12500.0
    2    jay    10000    周杰伦    10000.0

    - 使用lambda表达式

    df['after_sal']=df['salary'].map(lambda s:s-(s-10000)*0.5)

    注意:并不是任何形式的函数都可以作为map的参数。只有当一个函数具有一个参数且有返回值,那么该函数才可以作为map的参数

    3. 使用聚合操作对数据异常值检测和过滤

    使用df.std()函数可以求得DataFrame对象每一列的标准差

    # 创建一个1000行3列的df 范围(0-1),求其每一列的标准差
    df = DataFrame(data=np.random.random(size=(1000,3)), columns=['A','B','C'])
    
        A              B                        C
    0    0.623677    0.296882    0.180331
    1    0.151164    0.838745    0.074804
    2    0.810686    0.278847    0.632431
    3    0.949126    0.836832    0.363521
    .............................
    
    # 对df应用筛选条件,去除标准差太大的数据:假设过滤条件为 C列数据大于两倍的C列标准差
    
    value_std = df['C'].std() * 2
    df['C'] <= value_std 
    df.loc[df['C'] <= value_std ]

    4. 排序

    使用.take()函数排序

    - take()函数接受一个索引列表,用数字表示,使得df根据列表中索引的顺序进行排序
    - eg:df.take([1,3,4,2,5])

    可以借助np.random.permutation()函数随机排序

    # 对列进行乱序
    df.take([2,1,0],axis=1)
         C                B                   A
    0    0.227520    0.448755    0.946236
    1    0.651939    0.880108    0.395235
    2    0.917283    0.914232    0.584911
    3    0.837992    0.267088    0.821250
    4    0.489001    0.435002    0.901875
    # np.random.permutation(x)可以生成x个从0-(x-1)的随机数列
    random_df = df.take(np.random.permutation(1000), axis=0).take(np.random.permutation(3), axis=1)
    random_df[0:100]
    
               C                  B          A
    290    0.712080    0.287919    0.798695
    188    0.148218    0.500367    0.334136
    335    0.789687    0.518180    0.951512
    617    0.196197    0.740249    0.065249
    ............................
    
    # 随机抽样
    # 当DataFrame规模足够大时,直接使用np.random.permutation(x)函数,就配合take()函数实现随机抽样

    5. 数据分类处理【重点】

    数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。

    数据分类处理:

    • 分组:先把数据分为几组
    • 用函数处理:为不同组的数据应用不同的函数以转换数据
    • 合并:把不同组得到的结果合并起来

    数据分类处理的核心:

     - groupby()函数
     - groups属性查看分组情况
     - eg: df.groupby(by='item').groups

    分组

    df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
                    'price':[4,3,3,2.5,4,2],
                   'color':['red','yellow','yellow','green','green','green'],
                   'weight':[12,20,50,30,20,44]})
    df
    # 使用groupby实现分组
    df.groupby(by='item', axis=0).groups
    {'Apple': Int64Index([0, 5], dtype='int64'),
     'Banana': Int64Index([1, 3], dtype='int64'),
     'Orange': Int64Index([2, 4], dtype='int64')}
    
    # 计算出苹果的平均价格
    df.groupby(by='item',axis=0).mean()['price'][0]
    # 先取出列再运算节省计算成本
    df.groupby(by='item')['price'].mean()[0]
    
    # 按颜色查看各种颜色的水果的平均价格
    color_price = df.groupby(by='color')['price'].mean()
    dic = color_price.to_dict()
    df['color_mean_price'] = df['color'].map(dic)
    df
    
        item    price    color    weight    mean_price    color_mean_price
    0    Apple    4.0    red    12    3.00    4.000000
    1    Banana    3.0    yellow    20    2.75    3.000000
    2    Orange    3.0    yellow    50    3.50    3.000000
    3    Banana    2.5    green    30    2.75    2.833333
    4    Orange    4.0    green    20    3.50    2.833333
    5    Apple    2.0    green    44    3.00    2.833333
    
    # 汇总:将各种颜色水果的平均价格和df进行汇总
    mean_price = df.groupby(by='item')['price'].mean()
    dic = mean_price.to_dict()
    df['mean_price'] = df['item'].map(dic)
    df
    
    
    item    price    color    weight    mean_price
    0    Apple    4.0    red    12    3.00
    1    Banana    3.0    yellow    20    2.75
    2    Orange    3.0    yellow    50    3.50
    3    Banana    2.5    green    30    2.75
    4    Orange    4.0    green    20    3.50
    5    Apple    2.0    green    44    3.00

    6 高级数据聚合

    使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算

    • df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
    • transform和apply都会进行运算,在transform或者apply中传入函数即可
    • transform和apply也可以传入一个lambda表达式
    #使用apply函数求出水果的平均价格
    def fun(s):
        sum = 0
        for i in s:
            sum+=s
        return sum/s.size
    
    df.groupby(by='item')['price'].apply(fun)
    
    0    4.0
    1    3.0
    2    3.0
    3    2.5
    4    4.0
    5    2.0
    Name: price, dtype: float64
    
    #使用transform函数求出水果的平均价格
    df.groupby(by='item')['price'].transform(fun)
    df
    
    
    item    price    color    weight    mean_price    color_mean_price
    0    Apple    4.0    red    12    3.00    4.000000
    1    Banana    3.0    yellow    20    2.75    3.000000
    2    Orange    3.0    yellow    50    3.50    3.000000
    3    Banana    2.5    green    30    2.75    2.833333
    4    Orange    4.0    green    20    3.50    2.833333
    5    Apple    2.0    green    44    3.00    2.833333
  • 相关阅读:
    【服务后端】Django 返回的QuerySet序列化
    【服务后端】Django的多表数据查询
    【微信开发】2、全局Token获取
    【微信开发】1、服务器响应,与微信服务器握手
    【服务后端】Python序列化对象为Json方法
    【服务后端】Django对比查询结果中的id时报错'dict' object has no attribute 'id'
    【网页前端】WeX5架构下,WinDialog子窗口1传递参数给主窗口关闭,再弹出子窗口2失败
    【系统运维】CentOS系统MySql,Tomcat和Django自启动
    【网络开发】WeX5的Ajax和Django服务器json接口对接跨域问题解决
    21.1
  • 原文地址:https://www.cnblogs.com/harryblog/p/10818251.html
Copyright © 2020-2023  润新知