美文网首页
数据分析入门

数据分析入门

作者: Aptitude | 来源:发表于2019-03-02 22:38 被阅读0次

    数据分析

    1.matplotlib折线图

    matplotlib:最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建

    from matplotlib import pyplot as plt
    
    '''
    设置图片大小
    figure表示图形图标的意思,这里指画的图
    通过实例化一个figure并且传递参数,能够在后台自动使用该figure实例
    在图像模糊的时候可以传入dpi参数,让图片更加清晰
    '''
    fig = plt.figure(figsize=(20,8),dpi = 80)
    x = range(120)
    y = [15,13,14.5,17,20,25,26,26,24,22,18,15]
    #传入x和y,通过plot绘制折线图
    plt.plot(x,y)
    #设置x的刻度
    plt.xticks(x)
    plt.savefig("fig1.png")  #保存图片
    #在执行程序的时候展示图形
    plt.show()
    

    实例
    假设大家在30岁的时候,根据自己的实际情况,统计出来了你和你同桌各自从11岁到30岁每年交的女(男)朋友的数量如列表a和b,请在一个图中绘制出该数据的折线图,以便比较自己和同桌20年间的差异,同时分析每年交女(男)朋友的数量走势

    a = [1,0,1,1,2,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1]

    b = [1,0,3,1,2,2,3,3,2,1 ,2,1,1,1,1,1,1,1,1,1]

    要求:
    y轴表示个数

    x轴表示岁数,比如11岁,12岁等
    
    from matplotlib import pyplot as plt
    import random
    
    plt.figure(figsize = (15,8))
    x = [i for i in range(11,31)]
    a = [1,0,1,1,2,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1]
    b = [1,0,3,1,2,2,3,3,2,1 ,2,1,1,1,1,1,1,1,1,1]
    plt.plot(x,a,label = "myself",linestyle = "--",color = "red",alpha = 0.5)
    plt.plot(x,b,label = "you",linestyle = "-",color = "orange",alpha = 0.5)
    plt.legend(loc="best")  #图例的地方
    plt.xticks(x[:31:1])
    plt.xlabel("age")
    plt.ylabel("number")
    plt.title("the number of friend in this year")
    plt.show()
    
    实例结果

    1.1.2 绘制散点图

    实例
    假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规律?

    a = [11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]

    b = [26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]

    from matplotlib import pyplot as plt
    
    y_3 = [11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]
    y_10 = [26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]
    
    x_3 = range(1,32)
    x_10 = range(51,82)
    
    plt.figure (figsize = (20,8),dpi=80)
    plt.scatter(x_3,y_3,label = "March")
    plt.scatter(x_10,y_10,label = "October")
    #调整x轴的刻度
    _x= list(x_3)+list(x_10)
    _xtick_labels = ["3.{}".format(i) for i in x_3]
    _xtick_labels +=["10.{}".format(i-50) for i in x_10]
    plt.xticks(_x[::3],_xtick_labels[::3])
    #添加图例
    plt.legend(loc="upper left")
    #增加描述信息
    plt.xlabel("Day")
    plt.ylabel("Temperature")
    plt.title("Title")
    plt.show()
    
    实例结果

    1.1.3 绘制条形图

    #绘制竖向条形图
    plt.bar(x,y,width=0.3)
    #绘制横向条形图
    plt.barh(x,y,width=0.3)
    

    1.1.4 绘制多次条形图

    假设你知道了列表a中电影分别在2017-09-14(b_14), 2017-09-15(b_15), 2017-09-16(b_16)三天的票房,为了展示列表中电影本身的票房以及同其他电影的数据对比情况,应该如何更加直观的呈现该数据?

    a = ["Film1","Film2","Film3","Film4"]

    b_16 = [15746,312,4497,319]

    b_15 = [12357,156,2045,168]

    b_14 = [2358,399,2358,362]

    from matplotlib import pyplot as plt
    
    a = ["Film1","Film2","Film3","Film4"]
    b_16 = [15746,312,4497,319]
    b_15 = [12357,156,2045,168]
    b_14 = [2358,399,2358,362]
    
    bar_width = 0.2
    x_14 = list(range(len(a)))
    x_15 = [i+bar_width for i in x_14]
    x_16 = [i+bar_width*2 for i in x_14]
    
    plt.figure(figsize=(20,8),dpi=80)
    plt.bar(range(len(a)),b_14,width=bar_width,label="Sep.14")
    plt.bar(x_15,b_15,width=bar_width,label="Sep.15")
    plt.bar(x_16,b_16,width=bar_width,label="Sep.16")
    plt.legend()
    plt.xticks(x_15,a)
    plt.xlabel("film")
    plt.ylabel("number")
    plt.show()
    
    实例结果

    1.1.5 绘制直方图

    假设你获取了250部电影的时长(列表a中),希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据?
    a=[131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]

    from matplotlib import pyplot as plt
    
    a = [131,  98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115,  99, 136, 126, 134,  95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117,  86,  95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123,  86, 101,  99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140,  83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144,  83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137,  92,121, 112, 146,  97, 137, 105,  98, 117, 112,  81,  97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112,  83,  94, 146, 133, 101,131, 116, 111,  84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]
    d = 3
    num_bins = (max(a)-min(a))
    plt.figure(figsize = (20,8),dpi = 80)
    plt.hist(a,num_bins)
    plt.xticks(range(min(a),max(a)+d,d))
    plt.grid()
    plt.show()
    
    实例结果

    2. Numpy

    Numpy:一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算。

    2.1 数组

    2.1.1 数组与数字的运算

    #创建数组
    a = np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
    b = np.array(range(1,6))
    c = np.arrange(1,6)
    #查看数组的类名
    type(a)  #输出:numpy.ndarray
    #查看数据的类型
    a.dtype  #输出:dtype('int64')
    #查看数组的形状
    a.shape()  #输出:(2,6)
    #将二维数据展开为一维的
    a.flattern()  
    #数组的加法,减法,乘法,除法,类似。numpy的广播机制,作用在所有元素上
    a + 2
    '''
    输出
    [[ 5  6  7  8  9 10]
     [ 6  7  8  9 10 11]]
    '''
    

    2.1.2 数组与数组的运算

    • 维度一样时,对应位进行运算;
    • 维度不同时,若其中一个维度相同,另一个维度为1的话,可以进行运算。否则不能进行运算
    import numpy as np
    a = np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
    b = np.array([[1],[2]])
    c = a + b
    print(c)
    #输出:
    [[ 4  5  6  7  8  9]
     [ 6  7  8  9 10 11]]
    

    广播原则:
    如果两个数组的后缘维度,即从末尾开始算起的维度的轴长度相符或其中一方的长度为2,则认为它们是广播兼容的。广播会在缺失和长度为1的维度上进行。

    2.1.3 轴的概念

    二维数组的轴(图源黑马程序员)
    三维数组的轴(图源黑马程序员)

    2.2 numpy读取数据

    2.2.1 从CSV中读数据

    CSV:Comma-Separated Value,逗号分隔值文件
    显示:表格状态
    源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录

    由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据

    np.loadtxt(fname, dtype=np.float, delimiter=None, skiprows=0, usecols=None, unpack=False)

    import numpy as np
    us_file = "data_numbers.csv"
    '''
    其中,us_file表示路径;
    delimiter表示数据是以什么作为分割的;
    dtype表示数据类型,默认情况下对于较大数据会变为科学计数的方式
    unpack=true表示将数据矩阵进行转置
    '''
    np.loadtext(us_file,delimiter=",",dtype="int",unpack = True)
    

    numpy中的转置

    t = np.array([[],[],[]])
    #第一种
    t.transpose()
    #第二种,交换0和1轴
    t.swapaxes(1,0)
    t.T
    

    2.2.2 索引和切片

    a[1]  #取1行
    a[:,2]  #取1列
    a[1:3]  #取多行
    a[:,2:4]  #取多列
    a[:,2:4] = 0
    a[t<10] = 0 #将t中<10的都替换为0
    #numpy的三元运算符,将<10的替换为0,将>=10的替换为10
    np.where(t<10,0,10)
    #将<10的替换为10,大于18的替换为18
    t.clip(10,18)
    

    2.2.3 numpy中的nan和inf

    • nan(NAN,Nan):not a number表示不是一个数字。当我们读取本地的文件为float的时候,如果有缺失,就会出现nan
      当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)

    • inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷。比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)。

    #指定一个nan或inf
    a = np.inf
    b = mp.nan
    type(a)  #输出:float
    type(b)  #输出:float
    

    2.2.4 numpy中常用统计函数

    #其中,默认返回多维数组的全部统计结果,如果指定axis则返回一个当前轴上的结果
    t.sum(axis=None)  #求和
    t.mean(a,axis=None) #均值
    t.median(t,axis=None) #中值
    t.max(axis=None) #最大值
    t.min(axis=None) #最小值
    np.ptp(t,axis=None)  #极差
    t.std(axis=None)  #标准差
    

    2.3 其他一些方法

    2.3.1 数组的拼接

    #竖直拼接
    np.vstack((t1,t2))
    #水平拼接
    np.hstack((t1,t2))
    

    2.3.2 数组的行列交换

    #行交换
    t[[1,2],:] = t[[2,1]:]
    #列交换
    t[:,[0,2]] = t[:,[2,0]]
    

    2.3.3 一些方法

    #获取最大值,每一行的最大值位置
    np.argmax(t,axis=0)
    #获取最小值,每一列最大值的位置
    np.argmin(t,axis=1)
    #创建全为0的数组
    np.zeros((3,4))
    #创建全为1的数组
    np.ones((3,4))
    #创建对角线为1的正方形数组(方阵)
    np.eve(3)
    

    2.3.4 生成随机数

    #创建一个4*5的在10-20之间的整数
    np.random.randint(10,20,(4,5))
    #随机数种子,s是给定的种子值,通过设定相同的随机数种子,可以每次生成相同的随机数
    np.random.seed(10)
    t=np.random.randint(0,20,(3,4))
    print(t)
    

    2.3.5 copy与view

    • a=b 完全不复制,a和b相互影响;
    • a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的;
    • a = b.copy(),复制,a和b互不影响。

    3. Pandas

    numpy能够帮助我们处理数值,但是pandas除了处理数值之外(基于numpy),还能够帮助我们处理其他类型的数据。

    pandas的常用数据类型:

    • Series 一维,带标签数组;
    • DataFrame 二维,Series容器。

    3.1 Series

    3.1.1 创建

    • 通过一个列表创建;
    • 通过一个字典创建,前面为值,后面为键。
    import pandas as pd
    import string
    import numpy as np
    #前面为数值,后面为键
    t = pd.Series(np.arange(10),index = list(string.ascii_uppercase[:10]))
    print(t)
    print(t.dtype)  #输出:int
    print(type(t))
    #通过字典方式创建
    a ={"age":22,"name":"Mary","emotion":"happy"}
    print(a)
    print(type(a))
    a = pd.Series(a) #创建Series
    print(a)
    print(a.dtype)  #输出:object。只要有字符串就是object
    print("*"*100)
    b = {string.ascii_uppercase[i]: i for i in range(10)}
    b = pd.Series(b,index=list(string.ascii_uppercase[5:15]))
    print(b)
    print(b.dtype)
    

    3.1.2 切片和索引

    • 切片:直接传入start,end或者步长即可;
    • 索引:一个的时候直接传入序号或者index,多个的时候传入序号或者index的列表。
    import pandas as pd
    import string
    import numpy as np
    b = {string.ascii_uppercase[i]: i for i in range(10)}
    b = pd.Series(b,index=list(string.ascii_uppercase[5:15]))
    print(b)
    print(b.dtype)
    print(b[2:10:2])
    print(b[[5,6,7]])  #注意两层括号索引
    print(b[b>6])
    print(b[["F","H","I"]])
    print(b.index)
    print(b.values)
    print(type(b.index))
    print(type(b.values))
    #输出:
    Index(['F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'], dtype='object')
    [ 5.  6.  7.  8.  9. nan nan nan nan nan]
    <class 'pandas.core.indexes.base.Index'>
    <class 'numpy.ndarray'>
    

    因此,Series对象本质上由两个数组构成,一个数组构成对象的键(index,索引),一个数组构成对象的值(values),键->值。

    2.1.3 读取外部数据

    #pandas读取CSV中的文件
    df = pd.read_csv("myfile.csv")
    

    2.2 DataFrame

    import pandas as pd
    import numpy as np
    a = pd.DataFrame(np.arange(12).reshape(3,4))
    print(a)
    #指定行索引和列索引
    b = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list("wxyz"))
    print(b)
    
    #通过字典传入数据,一种方式
    c = {"name":["xiaoming","xiaogang"],"age":[20,32],"tel":[10085,34895]}
    c = pd.DataFrame(c)
    print(c)
    #第二种方式
    d=[{"name":"xiaohong","age":32,"tel":10058},{"name":"xiaogang","age":32,"tel":11058}]
    d = pd.DataFrame(d)
    print(d)
    
    d=[{"name":"xiaohong","age":32,"tel":10058},{"name":"xiaogang","age":32,"tel":11058},{"name":"xiake","age":52,"tel":10038}]
    d = pd.DataFrame(d)
    print(d.shape)  #行数,列数
    print(d.dtypes)  #列数据类型
    print(d.ndim)  #数据维度
    print(d.index)  #行索引
    print(d.columns)  #列索引
    print(d.values)  #对象值,二维ndarray数组
    print("+"*100)
    print(d.head(2))  #显示头部前2行
    print(d.tail(2))  #显示尾部后2行
    print(d.info())  #相关信息概览:行数,列数,列索引,列非空值个数
    print("/"*100)
    print(d.describe())  #快速综合统计结果:计数,均值,标准差,最大值,四分位数,最小值
    

    DataFrame对象既有行索引,又有列索引。

    • 行索引,表明不同行,横向索引,叫index,0轴,axis=0;

    • 列索引,表明不同列,纵向索引,叫columns,1轴,axis=1。

    2.2.1 取行或取列及数据的处理

    import pandas as pd
    import numpy as np
    
    b = pd.DataFrame(np.arange(12).reshape(3,4),index=list("ABC"),columns = list("WXYZ"))
    print(b)
    #loc通过标签索引行数据
    b.loc["A","W"]
    b.loc["A",["W","Z"]]
    b.loc[["A","C"],["W","Z"]]
    b.loc["A":"C",["W","Z"]]
    #iloc通过位置获取行数据
    b.iloc[1:3,[2,3]]
    b.iloc[1:3,1:3]
    #赋值更改数据
    b.iloc[1:2,0:2] = 200
    b.loc["A","Y"] = 100
    #实现布尔索引,不同的额条件之间需要用括号括起来
    b[(b["Row_Labels"].str.len()>4) & (b["Count_AnimalName"]>700)]
    
    '''
    缺失数据常见的处理方式
    判断数据是否为NaN:
    处理方式1:删除NaN所在的行列
    处理方式2:填充数据
    '''
    pd.isnull(b)
    pd.notnull(b)
    b.dropna(axis = 0,how='any',inplace=False)  #方式1
    b.fillna(b.mean())  #方式2,填充平均值
    b.fiallna(b.median())  #方式2,填充中位数
    b.fillna(0)  #方式3,填充0
    #处理为0的数据
    b[b==0]=np.nan
    

    2.2.2 数据合并

    import pandas as pd
    import numpy as np
    
    t1 = pd.DataFrame(np.ones((2,4)),index=["A","B"],columns=list("abcd"))
    t2 = pd.DataFrame(np.zeros((3,3)),index=["A","B","C"],columns=list("xyz"))
    #按照行索引进行合并
    print(t1.join(t2))
    print(t2.join(t1))
    #输出:
         a    b    c    d    x    y    z
    A  1.0  1.0  1.0  1.0  0.0  0.0  0.0
    B  1.0  1.0  1.0  1.0  0.0  0.0  0.0
         x    y    z    a    b    c    d
    A  0.0  0.0  0.0  1.0  1.0  1.0  1.0
    B  0.0  0.0  0.0  1.0  1.0  1.0  1.0
    C  0.0  0.0  0.0  NaN  NaN  NaN  NaN
    #merge,这是有相同值的情况
    t1.merge(t2,on="a")  #默认内连接,求交集
    t1.merge(t2,on='a',how="outer")  #外连接,并集
    t1.merge(t2,on="a",how="left")  #以t1为准,并集
    t1.merge(t2,on="a",how="right")  #以t2为准,并集
    #若没有相同值ze进行指定列索引
    t1,mnerge(t2,left_on="o",right="x",how="outer")
    

    2.3 分组和聚合

    这里的内容类似SQLserver中的内容,在此没有深究。如果不常用的话容易忘记。

    2.4 时间序列

    pd.date_range(start=None, end=None, periods=None, freq='D')
    start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引
    start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索引

    t4 = pd.date_range(start="20170101",end="20171225",freq="BM")
    print(t4)
    #输出:
    DatetimeIndex(['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-28',
                   '2017-05-31', '2017-06-30', '2017-07-31', '2017-08-31',
                   '2017-09-29', '2017-10-31', '2017-11-30'],
                  dtype='datetime64[ns]', freq='BM')
    

    关于频率的更多缩写,如图。


    频率缩写(图源黑马程序员)

    2.4 重采样

    重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样。

    pandas提供了一个resample的方法来帮助我们实现频率转化。
    具体的应用实例不学习了,数据分析入门结束,接下来进入正题。

    相关文章

      网友评论

          本文标题:数据分析入门

          本文链接:https://www.haomeiwen.com/subject/ytzeuqtx.html