zoukankan      html  css  js  c++  java
  • 数据分析常用工具总结

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    1. 优点:向量化数据操作比for循环,速度大大加强,numpy array比list好的地方在于切片
    2. array属性
    np.random.random((2,2)) # 0-1随机数
    np.random.randint(1,10,(3,3)) # 随机整数
    array.shape, array.dtype # numpy两个属性
    array.astype(np.float64) # 类型转换
    3. array切片操作
    a[0,1] # 第一个维度为0,第二个维度1,第三个维度全选,类似于a[0,1,:]
    a[a>2] # boolean indexing, 利用broadcasting进行判断, 之后可以作为index进行数据的提取
    a[a>2]=0 # 也可以对满足条件的元素进行赋值
    4. array数学运算
    broadcasting, 对不匹配的数据在高维上进行扩展,在取最小公倍数
    np.sum(array) # 统计运算
    np.dot # 矩阵乘法,点乘
    np.multiply # 逐个元素乘法,对应相乘

    #pandas

    1
    2
    3
    基于Numpy构建,利用它的高级数据结构和操作工具,可使数据分析工作变得更加便捷高效。
    import numpy as np
    import pandas as pd

    基本数据结构

    Series

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    1. 基本概念
    pd.__version__ # 查看版本
    pd.Series # 可以使用不同类型,和list区别在于有index, 可以指定index

    2. Series构建
    pd.Series([1,2,3], index=['a', 'b', 'c'])
    pd.Series({...}, name="xxx") # 通过对dictionary进行构建pandas, 给Series赋予名字

    3. 切片
    aseries[[1,4,3]]; aseries[1:]; aseries[:-1] # 数字下标切片,即使index不是数字也ok

    4. 运算规则
    series的相加是根据index对应相加的

    5. 取值
    数学运算也是broadcasting方式
    'xxx' in aseries # 判断xxx是否在aseries的index中
    aseries.get('xxx', 0) # 类似于字典
    aseries[aseries<20] # boolean index也可以
    aseries.median() # 除去缺失值之后进行统计运算
    aseries['xxx'] = 1000 # 对aseries['xxx']重新赋值
    np.square(aseries) # 对每个运算进行计算平方

    DataFrame

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    1. 基本概念
    一组Series集合在一起

    2. DataFrame的构建
    - pd.DataFrame({'a':[1,2,3], 'b':[1,4,3]}, columns = ['b', 'a'], index = ['one', 'two', 'three']) # 构建DF, 指定列名以及index名
    - pd.DataFrame([{'a':100,'b':200}, {'a':200, 'b':300}], index=['one', 'two']) # 按照一行一行构建DF
    - pd.DataFrame({'a':seriesa, 'b':seriesb} # 记住按照index对齐, 缺失值直接Nan填充

    3. 元素的提取以及增加及逻辑操作及转置
    - aDF['xxx']/aDF.xxx # 取出来的是一个Series
    - aDF[['xxx']] # 取出来的是一个DF
    - aDF.loc(['a','b'],['c','d']) # 取对应的数据
    - aDF.loc[:, 'newcol'] = 2000 # 如果没有newcol那么就新加一列
    - aDF.loc[(aDF['a']>10) & (aDF['b']<100), :] # 也可以给条件进行筛选,& | ~进行逻辑运算
    - aDF.T # 进行转置
    4. 数据读入以及基本信息以及删除
    - pd.read_csv(path, sep='t', index_col=''/int, usecols=[...], header=0, parse_dates=[0]/['Date']) # 读文件,第一列作为日期型,日期型处理参照: http://hshsh.me/post/2016-04-12-python-pandas-notes-01/
    - aDF.to_csv('xxx.csv', sep='t', index=True, header=True) # 写文件
    - aDF.describe(include=[np.float64...]) / aDF.info() # 对数据进行统计,查看缺失值
    - aDF.shape
    - aDF.isnull() # 判断是是否为空
    - aDF[aDF['xxx'].isnull(), :] = 10 # 对空值赋值
    - aDF.notnull() # 查看是否有值
    - aDF.drop(['one', 'two'], axis=0) # 对index为one和two的两行进行删除, axis=1删除列

    5. 数据分组聚合
    - aDF.groupby('name', sort=False).sum() # 对DF进行聚合操作,同时对相应聚合的列进行排序,然后计算其他值的和
    - groupbyname=aDF.groupby('name'); groupbyname.groups; len(groupbyname) # 得到对应的各个组别包含的index, 并且可以获取对应的group长度
    - aDF.groupby('name').agg([np.sum, np.mean, np.std]) # 对不同类别的数据进行各类运算, 每个name对应三列分别是分组之后np.sum, np.mean, np.std计算
    - aDF.groupby('name').agg(['sum', 'median', 'mean']) # 和上面的作用相同
    - aDF.groupby('name').agg(['a':np.sum, 'b':median, 'c':np.mean]) # 对不同列进行不同操作
    - aDF.groupby(['name', 'year']).sum()/mean()/median()/describe() # 多组分类
    - aDF.groupby(['name', 'year']).size() # 多组分类, 每一组有多少个记录
    - 提取group类别名称以及类别对应的数据行
    for name,group in groupbyname:
    print(name) # 类别名称
    print(group) # 名称对应的数据行
    groupbyname.get_group('jason') # 可以得到对应组别的数据行,DF格式
    6. transform/apply/filter 数据变换
    transfrom可以对分组进行变换, apply对整个DF进行分类,filter对分组进行判断
    - aDF['Date'].dt.dayofweek # 可以得到对应的日期中的第几天
    - aDF.groupby(aDF.index.year).mean() # 可以对相应的日期型的年进行分组聚合
    - aDF.groupby(aDF.index.year).transform(lambda x: (x-x.mean())/x.std()) # 对每一年的数据求均值以及标准差,并对每个数据进行操作,之所以没以每年为单位进行展示主要是跟function有关,因为之前的是mean之类的
    - aDF.groupby(aDF.index.year).apply(lambda x: (x-x.mean())/x.std()) # 可以起到相同的效果
    - aDF.loc[:,'new'] = aDF['xxx'].apply(afunc) # 可以对xxx这一列进行操作按照afunc进行操作,然后创建新的列
    - aSer = pd.Series([1,1,2,2,2,3,3,4,5,5]); sSer.groupby(sSer).filter(lambda x:x.sum()>4) # 对ser进行过滤,留下那些和大于4的类别

    7. 表格的拼接与合并(concat/append/merge/join)
    - df1.append(df2, sort=False, ignore_index=True) # 追加在行上,同时忽略原先df1和df2的index,合并为新的index
    - df1.append([df2, df3]) # 也可以追加两个DF, 参考: https://zhuanlan.zhihu.com/p/38184619
    - pd.concat([df1.set_index('a'), df2.set_index('a')], sort=False, axis=1, join='inner') # 和上述利用merge在a字段上进行内连接的效果类似,因为concat是基于index进行连接的,merge可以不基于index,指定字段
    - pd.concat([df1, df2, df3], keys=['a', 'b', 'c'], axis=0, join='outer', sort=False) #列对齐的方式对行进行拼接,缺少值则补充为None,可以对拼接的每个df进行key的命名,axis=1的时候行对齐列拼接; join指定连接方式,outer表示外连接,inner表示内连接,sort是否对合并的数据进行排序
    - merge # 基于某个字段进行连接,之前的append和concat都是在行上或者列上进行连接的,merge类似于SQL里面的连接,可以指定某个字段或某几个字段,体现在on上,on接list就是多个字段为key
    - pd.merge(df1, df4, on='city', how='outer'/'inner'/'left'/'right') # 基于两个表中的city字段进行表格的连接,把其他的列进行combine到一起,不指定on的话就会找字段相同的那个进行拼接,注意concat是基于index进行拼接的
    大专栏  数据分析常用工具总结 - pd.merge(df1, df2, how='inner', left_index=True, right_on='id') # 对数据进行merge,左表以index作为连接关键字,右表用id作为关键字
    8. 链家Case study流程
    - pd.to_datetime() # 日期类型转换
    - df.drop(droplist, inplace=True, axis=1) # 删除一些列
    - aDF.describe(include='all') # 字符串变量也会同时统计
    - aDF.sort_values(by = 'xxx').tail() # 找出更新最晚的20套,但是有可能同一天超过20套
    - 如果对数据进行处理发现转换未果可能是因为数据有缺失,做异常处理,缺失值作为Nan
    - aDF.nsmallest(columns='age', n=20) # 取出年龄最小的20个数据
    - groupby().agg() 之后一般会使用reset_index() 对数据进行归置然后再进行操作,ascending=False
    - adf.value_counts(normalize=True) # 默认是按照value进行排序的
    - aDF.apply(lambda x: 'xxx' in x) # 筛选出xxx在某列的值中与否,返回Ture, False,正则表达式的字符串匹配
    - 可以定义正则表达式对文本信息进行提取
    def get_info(s, pattern, n):
    result = re.search(pattern, s)
    if result:
    return result.group(n)
    else:
    return ''
    - .astype(int) # 转换pd类型
    - help(pd.Series.value_counts) # 打印帮助文档

    python绘图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    1. pandas 绘图
    - pd.date_range('2018/12/28', periods=10) # 产生日期格式, 以2018/12/28为起始产生以天为单位的日期时间list
    - pandas绘图需要把横坐标作为index,之后再画图
    - 折线图绘制需要注意各列幅度,否则数值不明显
    - df.plot.bar() # barplot, stacked=True, 堆叠
    - df.plot.barh() # 绘制水平的barplot
    - df.plot.hist(bins = 20) # 绘制直方图,单维度
    - df.plot.box() # 对每列去看一些分布outlier
    - df.plot.area # 堆叠区域图
    - df.plot.scatter(x='a', y='b') # 散点图
    - df.plot.pie(subplots=True) # 绘制带图例的饼图

    2. matplotlib 绘图
    - plt.rcParams['figure.figsize'] = (12,8) / plt.figure(figsize=(12,8)) # 设置画布大小
    - ax = plt.plot(x,y,color='green', linewidth='-', marker='./*/x', label=r'$y=cos{x}$'/r'$y=sin{x}$'/r'$y=sqrt{x}$') # 绘图
    - ax.spines['right'].set_color('none') # 去掉右边的边框
    - ax.xaxis.set_ticks_position('bottem') # ??????????????
    - plt.xticks([2,4,6], [r'a',r'b',r'c']) # 设置坐标轴刻度
    - ax.spines['bottem'].set_position('data', 0) # 设置坐标轴从0开始
    - plt.xlim(1,3) # 设置坐标位置
    - plt.title() # 标题
    - plt.xlabel(r'xxx', fontsize=18, labelpad=12.5) # 绘制label, r值的是不转义的,$$值的是markdown格式
    - plt.text(0.8, 0.9, r'$$', color='k', fontsize=15) # 进行注解
    - plt.scatter([8], [8], 50, color='m') # 在某个位置,点有多大,颜色是什么
    - plt.annotate(r'$xxx$', xy=(8,8), xytext=(8.2, 8.2), fontsize=16, color='m', arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0.1', color='m')) # 对某个点进行注解, 进行加箭头等等
    - plt.grid(True) # 网格线
    - plt.plot(x, y) # xy应为np array,如果是pandas那么可以通过values进行取值转换
    3. matplotlib 绘图case
    - 文件解压
    x = zipfile.ZipFile(xxx, 'r') # 解压文件夹
    x.extractall('xxxdir') # 解压到某个文件夹下
    x.close() # 记得关闭
    - matplotlib.rc('figure', figsize=(14,7)) # 设置一下图片尺寸
    - matplotlib.rc('font', size=14) # 设置字体
    - matplotlib.rc('axes.spines', top=False, right=False) # 设置边线
    - matplotlib.rc('axes', grid=False) # 设置网格
    - matplotlib.rc('axes', facecolor='white') # 设置颜色
    - fig,ax含义
    fig,ax = plt.subplots() # 创建绘图对象之后对ax进行操作,相当于先fig=plt.figure()再ax=fig.add_subplot(1,1,1)
    https://blog.csdn.net/htuhxf/article/details/82986440
    - ax.fill_between(x, low, upper, alpha=) # 对回归进行置信度绘制
    - ax2 = ax1.twinx() # 共享同一个x轴
    - ax2.spines['right'].set_visible(True) # 对右侧坐标轴进行设置,得到相应的图
    - 图的使用
    关联分析:散点图,曲线图,置信区间曲线图,双坐标曲线图
    分布分析:堆叠直方图, 密度图
    组间分析:柱状图(带errorbar),boxplot,这个需要多看看,

    4. seaborn 绘图
    - 引入seaborn的同时也要引入matplotlib因为,是底层
    - 颜色设置
    sns.set(color_codes=True) # 一些集成的颜色
    https://seaborn.pydata.org/tutorial/color_palettes.html
    - sns.displot(x, kde=True, bins=20, rug=True, fit=stats.gamma) # histgram加密度线,样本分布情况, 拟合某些分布fit
    - sns.kdeplot # 类似于上面的,kde是每个样本用正态分布画,如果样本多,高度就高,之后再做归一化
    - sns.jointplot(x,y,data) # 绘制带有histgram以及散点图的图,两个变量
    - sns.pairplot(df) # 直接绘制各个列之间的散点图以及对应的histgram,多个变量
    - scatter plot的密度版
    with sns.axes_style('ticks'):
    sns.jointplot(x,y,data, kind='hex'/'kde',color='m') #相当于对点很多的时候,六角箱图就能体现出点的多少,kde是等高线,密度联合分布
    - 多图绘制1
    g = sns.PairGrik(df) # 各个列混合,产出n*n个格子
    g.map_diag(sns.kdeplot) # 对角线绘制
    g.map_offdiag(sns.kdeplot, cmap='Blues_d', n_levels=20) # 绘制对角线是kde密度图其他为等高线的图
    - 多图绘制2
    g = FaceGrid(row=[..],aspect=1.5, data=)
    g.map(sns.boxplot, x, y, hue, hue_order=[], ...)
    - 多图绘制3
    g = sns.PairGrid(data, x_vars=[], y_vars=[], aspect=0.5, size=3.5)
    g.map(sns.violinplot, palette='bright') # x_vars数量*y_vars数量个子图,然后每个子图都绘制violinplot
    - 关联分析 sns.lmplot
    · sns.lmplot(x, y, data) # 散点图+线性回归,95%置信区间,适用于连续值
    · sns.lmplot(x, y, data, x_jitter=0.08) # 左右抖动, 点如果离得近,会把点左右抖动开,适用于离散值
    · sns.lmplot(x, y, data, x_estimator=np.mean, ci=95, scatter_kws={'s':80}, order=2, robust=True) # 对于离散值还可以这样操作,先求均值和95置信区间,之后再进行拟合, scatter_kws对点进行操作,order是说对数据点进行二次方的分布,而不是线性分布,robust打开的作用是踢除异常点,然后再进行绘制图
    · sns.lmplot(x, y, data, x_estimator=np.mean, ci=95, scatter_kws={'s':80}, order=1, robust=True, logistic=True) # 相当于是说对二值化的数据进行logistic回归拟合,sigmoid拟合
    · sns.lmplot(x, y, data, hue, col, row, col_wrap, aspect=0.5) # 散点图.线性回归,95%置信区间,适用于连续值,hue进行分组类似于pandas里面的groupby, hue变量一定是个离散变量, col也可以加一个变量,可以把图分成多列,row可以多行,如果row,col以及hue都指定,那么相当于在pandas里面groupby三个内容,col_wrap用于之指定每个col中的绘图数量
    - sns.residplot() # 残差图
    - sns.barplot(x,y,hue,ci=None) # 是否打开置信区间
    - sns.stripplot(x, y, data, jitter =True) # 基于x为离散数据的,类似于散点图的boxplot
    - sns.swarmplot(x, y, data) # 蜂群图,类似于小提琴图的点版
    - sns.boxplot()
    - sns.violinplot(bw) # 属于kde以及boxplot的组合,既看了单变量分布,也看了各变量之间的差异
    - sns.violinplot(split=True, hue, inner='stick') # split将hue为两个类型的进行拼接绘制小提琴图,stick,每个样本绘制竖线
    - sns.countplot(x, data) # 绘制离散变量数量分布,类似于value_counts(),类似于barplot但是使用的统计量是数量
    - sns.pointplot(x, y, hue) # 查看离散变量x以及hue在离散变量y上的差别,使用均值,画点
    - sns.factorplot(x, y, hue, col, data, kind='swarm') # 是一种泛化的绘图函数
    - a.savefig('xx') # 进行图片存储 plt函数
  • 相关阅读:
    js 自定义属性
    js innerText、textContent、innerHTML的区别和各自用法
    js 的常用选择器
    js Array属性和用法
    js---String对象
    iframe自适应高度js
    thinkphp 的save()不能更新数据解决办法
    转义字符
    获取客户端真实ip
    thinkphp条件查询和模糊查询的一些方法
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12239860.html
Copyright © 2011-2022 走看看