探索性数据分析(单因子与对比分析)可视化:

    读取csv文件:

    1. import pandas as pd
    2. df = pd.read_csv('./data/HR.csv')

    让pandas在展示的时候展示出所有的字段而不做隐藏:

    1. pd.set_option('display.max_columns', None)

    查看前十条信息:

    1. df.head(10)

    理论:

    集中趋势:均值,中位数与分位数、众数
    均值常用于分析连续均匀分布的数值;
    中位数用于衡量异常数值的集中分布趋势;
    众数用于离散值的集中趋势衡量;
    分位数和前面的进行结合使用;
    分位数如何使用:讲数值从小到大进行排列,然后切分,最常用的是四分位数。

    四分位数计算方式:
    image.png

    离中趋势:标准差、方差:
    对离散程度的衡量;
    计算公式:image.png
    值越大代表数据越分散,值越小数据越集中。

    数据分布:偏态与峰态、正态分布与三大分布:
    偏态系数(偏度):数据平均值偏离状态的一种衡量。对于对称性的分布而言,中位数和均值应该非常接近。对于非对称的分布,中位数和平均值偏差较大,就称为有偏态的分布。

    当均值大于中位数代表正偏,反之代表副偏。
    计算公式image.png

    峰态系数(峰度):峰态系数是数据分布集中强度的衡量。数值越大,图像顶越尖;越小,分布越平缓。
    正态分布的峰态系数为3,如果另一个数据分布的峰态系数和正态分布的峰态系数上下之差大于2,说明这种分布不是正态分布。
    峰态系数作用:用来判断某种数据的分布趋势是否是可以当作正态分布来看。
    计算公式image.png

    抽样理论:抽样误差、抽样精度
    抽样误差与精度。

    pandas和scipy常用api:

    1. import pandas as pd
    2. import scipy.stats as ss
    3. # 可以指定分隔符号
    4. df = pd.read_csv('./data/HR.csv')
    5. # pandas中的两个重要的数据结构:DataFrame、Series
    6. print(type(df)) # DataFrame
    7. print(type(df['satisfaction_level'])) # Series
    8. # df求均值
    9. print(df.mean())
    10. # Series求均值
    11. print(df['satisfaction_level'].mean())
    12. # 求中位数
    13. print(df.median())
    14. print(df['satisfaction_level'].median())
    15. # 求分位数
    16. print(df.quantile(q=0.25))
    17. print(df['satisfaction_level'].quantile(q=0.25))
    18. # 求众数
    19. print(df.mode())
    20. print(df['department'].mode())
    21. # 查看离中趋势
    22. print(df.std()) # 标准差
    23. print(df['satisfaction_level'].std())
    24. print(df.var()) # 方差
    25. print(df['satisfaction_level'].var())
    26. # 求和
    27. print(df.sum())
    28. print(df['satisfaction_level'].sum())
    29. # 偏态系数
    30. print(df.skew())
    31. print(df['satisfaction_level'].skew())
    32. # 峰度系数
    33. print(df.kurt())
    34. print(df['satisfaction_level'].kurt())
    35. # 分布函数,需要利用scipy的统计包
    36. print(ss.norm.pdf(0.0)) # 代表的是标准正态分布给出x轴坐标求对应的函数值
    37. print(ss.norm.ppf(0.9)) # 正态分布从-inf, +inf 积分为1,这里代表了从-inf积分到哪个x轴坐标时得到的积分值为0.9
    38. print(ss.norm.cdf(2)) # 代表标准正态分布从-inf积分到2的累计概率为多少
    39. print(ss.norm.rvs(10)) # 随机生成10个符合正态分布的数字
    40. # f分布
    41. print(ss.f)
    42. # t分布
    43. print(ss.t)
    44. # 塌方分布
    45. print(ss.chi)
    46. # df抽样
    47. print(df.sample(n=10)) # 指定抽样个数
    48. print(df.sample(frac=0.001)) # 指定抽样百分比
    49. # 以上的抽样方法同样适用与Series中

    数据分类:

    定类数据:按事物的某种属性进行分类或者分组,数字大小代表类别,比如性别。
    定序数据:可以界定数据的大小,但是不能测定差值。
    定距:可以界定数据大小的同时,可以测定差值,但是无绝对零点,可以做加减运算,不能做乘除运算,比如温 度。
    定比:可以表现为数值,可以进行加减以及精确运算的数据,比如说身高、体重。

    区分定距和定比数据之间的区别:
    定距:温度,20摄氏度不是10摄氏度的两倍
    定比:年龄,50岁是25岁的两倍

    单属性分析:

    异常值分析:**让本可以代表某些属性的值失去了其数据原来的意义**
    连续异常值:对一个连续的按顺序排列的数据分析,找到其中位数,上四分位数、下四分位数;
    四分位间距:上四分位数和下四分位数的差距;
    分析过程:以四分位间距为基础,上四分位数向上取四分位间距的K倍(1.5 ~ 3)限定一个上界
    同理向下取K倍限定下界。上下界之间的是正常值,上下界之外的是异常值。
    异常程度划分:当K = 1.5时,边界的值为中等异常。
    当K = 3时,边界的值为非常的异常!
    连续异常值的处理:可以直接舍弃、用边界值代替异常值。具体看业务需求。

    离散异常值:离散的属性定义范围以外的值。
    举例:收入数据被离散化成 中、高、低 三个水平后,不在这个范围内的值就算是离散异常值。
    处理方式:直接舍弃、把所有的异常值全部当作一个值来处理。

    知识异常值:在限定知识与常识范围外的所有值均为异常值。

    对比分析:
    绝对数比较:对于数字数据进行直接比较,例如比较评分、收入等。
    相对数比较:含义广,把几个有联系的指标构成一个集合,将指标联合的方式很多,会构成多种不同集合。
    划分:1. 结构相对数

    1. 2. 比例相对数:总体内用不同部分的数值进行比较。<br /> 举例:对农业、工业、服务业,例如哪个产业相对于哪个产业发生的变化。
    2. 3. 比较相对数:同一时空下的相似或者同质的指标进行对比<br /> 举例:不同时期,同一商品的价格;不同互联网公司的待遇水平,但是注 意,在比较的时候要保证同质,即比较的两个公司都是互联网公司!
    3. 4. 动态相对数:一般有时间概念在里面,例如物理上的速度、用户数量的增速。
    4. 5. 强度相对数。

    分析实战:
    测试数据集:HR.csv
    对字段 last_evaluation进行的分析

    import pandas as pd
    import numpy as np
    
    df = pd.read_csv('./HR.csv')
    
    le_s = df['last_evaluation']
    
    print(le_s)
    
    # 分析空值 Series([], Name: last_evaluation, dtype: float64) 说明没有空值
    print(le_s[le_s.isnull()])
    
    # 均值: 67.37373216904412
    print(le_s.mean())
    
    # 标准差
    print(le_s.std())
    
    # 看最小值和最大值
    # 999999.0
    # 0.36
    # 数据可能存在问题
    print(le_s.max())
    print(le_s.min())
    
    # 偏度122.48265175204614 -> 说明均值比平均数大很多
    print(le_s.skew())
    
    # 峰度15001.999986807796 -> 不稳定
    print(le_s.kurt())
    
    # 查看大于一的值:15000    999999.0 属于完全偏离的值,需要被抛弃
    print(le_s[le_s > 1])
    
    le_s = le_s[le_s <= 1]
    
    print(le_s)
    
    # 利用四分位间距估算有无异常值
    q_low = le_s.quantile(q=0.25)
    q_high = le_s.quantile(q=0.75)
    
    q_interval = q_high - q_low
    
    print(q_interval)
    
    high_border = q_high + 1.5 * q_interval
    low_border = q_low - 1.5 * q_interval
    
    print(high_border)  #  1.335 包含了1
    print(low_border)  #
    print(le_s.mind())
    
    # 没有异常值
    
    # 得到直方图
    print(np.histogram(le_s.values, bins=np.arange(0.0, 1.1, 0.1)))
    

    分析思路:先整体的浏览一下待分析字段,看完应该在脑子里先明确:此待分析字段的大概取值范围是怎样的?是0 ~ 1 的概率型数据格式还是计数的数据格式;接下来带着上述的答案对异常值进行筛查,不同类型的字段,异常值的限定范围是不同的,但是可以根据字段含义做异常值的初步筛查:如果该字段代表概率等,所占百分比的小数形式时,取值范围在0 ~ 1 是一个基本的合理范围,如果不再该范围的一定可以被定义为异常值。此时可以看看最大值、最小值、平均值看看是不是数值特别离谱(跟罗列出来的数据进行相比)。看看最大值和最小值,他俩如果差距特别大,就像上述的案例一样,那么就要考虑数据中有异常值的存在了。然后另一个评估数据的异常值的方式就是利用四分位间距,通常上四分位 + 四分位间距 _ 1.5 ~ 下四分位 - 四分位间距 _1.5属于一个正常值范围。
    得到数据的各个分布区间:print(np.histogram(le_s.values, bins=np.arange(0.0, 1.1, 0.1))),利用这个数据格式可以作matplotlib的图像。

    数据分析:

    import pandas as pd
    import numpy as np
    
    df = pd.read_csv('./HR.csv')
    amh_s = df['time_spend_company']
    
    # 利用value_counts()用在Series中,对本列的数据进行整体的划分并求和
    print(amh_s.value_counts().sort_index())
    
    # 展示出DataFrame的所有列而不是省略展示
    pd.set_option('display.max_columns', None)
    
    # 切换Series 为 salary 这一列
    s_s = df['salary']
    
    # 现将异常值设置为空,然后dropna将空值删除即可
    # 对Series使用dropna
    print(s_s.where(s_s != 'nme').dropna())
    
    print(d_s.where(d_s != 'sale').dropna().value_counts())
    
    '''
    删除异常值的方法:对 DataFrame(整个表格) 使用 dropna,最好指明 axis 和 how
    
    说明:axis默认为0,代表删除维度为行级别,1设置为列级别删除。
        how 设置为 all 时,当本行、本列的数据全部为 nan 才执行删除
        how 设置为 any 时,当本行、本列的数据有一个 nan 时就执行删除
    
    Series的过滤语法:
    说明:df[过滤条件],接下来展示出来满足过滤条件的数据,可用来过滤异常值
    '''
    df = df.dropna(axis=0, how="any")
    df = df[df['last_evaluation'] <= 1][df['salary'] != 'nme'][df['department'] != 'sale']
    
    '''
    按照department进行分类后,对其他的聚合字段取平均值
    '''
    print(df.groupby("department").mean())
    
    '''
    DataFrame的语法,DataFrame.loc[[lines], [columns]] 用于过滤展示出来的数据,`:`代表所有的行或者所有的列
    
    '''
    print(df.loc[:, ['last_evaluation', 'department']].groupby('department').mean())
    
    # 计算极差
    print(df.loc[:, ['average_monthly_hours', 'department']].groupby('department')['average_monthly_hours']
          .apply(lambda x: x.max() - x.min()))
    

    作图实战:

    import pandas as pd
    import numpy as np
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    df = pd.read_csv('./HR.csv')
    
    df = df.dropna(axis=0, how="any")
    df = df[df['last_evaluation'] <= 1][df['salary'] != 'nme'][df['department'] != 'sale']
    
    print('##############################')
    print(df['time_spend_company'].value_counts())
    f = plt.figure()
    # 作图,以员工工作的平均年限为横坐标,分析离职率:
    # 分析:横坐标为员工的工作年限,纵坐标是对应的员工离职率,找到工作时间和离职率的关系
    # 将工作年限为聚类条件,所有的其他相对工作年限做聚合时取均值,即可得到一一对应的关系
    # sub_df = df.groupby('time_spend_company').mean()
    # 按照工作时间进行聚类
    sub_df = df.groupby('time_spend_company').mean()
    # 作图
    sns.pointplot(sub_df.index, sub_df['left'])
    print(sub_df)
    # plt.pie(df['department'].value_counts(normalize=True), labels=df.groupby['department'].index)
    plt.show()