zoukankan      html  css  js  c++  java
  • 数据分析

    数据分析

    含义:

      是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律

      数据分析三剑客:Numpy,Pandas,Matplotlib

    Numpy

      NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

    创建ndarray

    1.使用np.array()创建

    import numpy as np
    
    # 一维数据的创建
    np.array([1,2,3,4,5])
    
    --- array([1, 2, 3, 4, 5])
    
    # 二位数据创建
    np.array([[1,2,3],[4,5,6]])
    
    --- array([[1, 2, 3],
           [4, 5, 6]])
    
    np.array([[1,2.2,3],[4,5,6]])
    ---  array([[1. , 2.2, 3. ],
           [4. , 5. , 6. ]])
    # numpy默认ndarray的所有元素的类型是相同的
    # 如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str>float>int

    照片数据的引入

    import matplotlib.pyplot as plt
    
    #引入照片,并进行显示
    img_arr = plt.imread('./meinv.jpg')
    plt.imshow(img_arr)

    打印结果:

    2. 使用np的routines函数创建

    #np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) 等差数列
    
    np.linspace(1,100,num=20)
    
    ---  array([  1.        ,   6.21052632,  11.42105263,  16.63157895,
            21.84210526,  27.05263158,  32.26315789,  37.47368421,
            42.68421053,  47.89473684,  53.10526316,  58.31578947,
            63.52631579,  68.73684211,  73.94736842,  79.15789474,
            84.36842105,  89.57894737,  94.78947368, 100.        ])
    
    
    #使用该方法让数值进行相等增加
    #np.arange([start, ]stop, [step, ]dtype=None)
    
    np.arange(0,100,step=2)
    
    ---  array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
           34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,
           68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98])
    
    
    # np.random.randint(low, high=None, size=None, dtype='l')
    
    np.random.seed(10)  #随机因子/时间种子
    np.random.randint(0,100,size=(4,5))
    
    
    ---   array([[ 9, 15, 64, 28, 89],
           [93, 29,  8, 73,  0],
           [40, 36, 16, 11, 54],
           [88, 62, 33, 72, 78]])

    ndarray的属性

      4个必记参数: ndim:维度 shape:形状(各维度的长度) size:总长度  dtype:元素类型

    #显示数据维度
    img_arr.ndim
    
    --- 3
    
    #显示各维度长度
    img_arr.shape
    
    ---  (456, 730, 3)
    
    #显示总长度
    img_arr.size
    
    ---  998640
    
    #显示元素类型
    type(img_arr)
    
    ---  numpy.ndarray

    ndarray的基本操作

    索引

    arr = np.random.randint(0,100,size=(5,7))
    arr
    ---   array([[49, 51, 54, 77, 69, 13, 25],
           [13, 92, 86, 30, 30, 89, 12],
           [65, 31, 57, 36, 27, 18, 93],
           [77, 22, 23, 94, 11, 28, 74],
           [88,  9, 15, 18, 80, 71, 88]])
    
    # 根据索引修改数据
    #查询第二行第三行数据
    arr[[1,2]]
    ---   array([[13, 92, 86, 30, 30, 89, 12],
           [65, 31, 57, 36, 27, 18, 93]])
    
    #查询第二行数据
    arr[1]
    ---   array([13, 92, 86, 30, 30, 89, 12])
    
    #查询二行第三列的数据
    arr[1,2]
    ---  86

    切片

    #获取二维数组前两行
    arr[0:2]
    ---   array([[49, 51, 54, 77, 69, 13, 25],
           [13, 92, 86, 30, 30, 89, 12]])
    
    #获取二维数组前两列
    arr[:,0:2] #arr[hang,lie]
    ---  array([[49, 51],
           [13, 92],
           [65, 31],
           [77, 22],
           [88,  9]])
    
    #获取二维数组前两行和前两列数据
    arr[0:2,0:2]
    ---   array([[49, 51],
           [13, 92]])
    
    #将数据反转,例如[1,2,3]---->[3,2,1],::进行切片
    #将数组的行倒序
    arr[::-1]
    ---  array([[88,  9, 15, 18, 80, 71, 88],
           [77, 22, 23, 94, 11, 28, 74],
           [65, 31, 57, 36, 27, 18, 93],
           [13, 92, 86, 30, 30, 89, 12],
           [49, 51, 54, 77, 69, 13, 25]])
    
    #列倒序
    arr[:,::-1]
    ---   array([[25, 13, 69, 77, 54, 51, 49],
           [12, 89, 30, 30, 86, 92, 13],
           [93, 18, 27, 36, 57, 31, 65],
           [74, 28, 11, 94, 23, 22, 77],
           [88, 71, 80, 18, 15,  9, 88]])
    
    #全部倒序
    arr[::-1,::-1]
    ---  array([[88, 71, 80, 18, 15,  9, 88],
           [74, 28, 11, 94, 23, 22, 77],
           [93, 18, 27, 36, 57, 31, 65],
           [12, 89, 30, 30, 86, 92, 13],
           [25, 13, 69, 77, 54, 51, 49]])
    
    
    #将图片进行全倒置操作
    plt.imshow(img_arr[:,::-1,:])
    
    plt.imshow(img_arr[::-1,:,:])
    
    #对图片进行截取操作
    plt.imshow(img_arr[115:340,145:580,:])

    变形

    使用arr.reshape()函数,注意参数是一个tuple!
    
    将一维数组变形成多维数组
    arr_1.reshape((-1,5))
    ---   array([[49, 51, 54, 77, 69],
           [13, 25, 13, 92, 86],
           [30, 30, 89, 12, 65],
           [31, 57, 36, 27, 18],
           [93, 77, 22, 23, 94],
           [11, 28, 74, 88,  9],
           [15, 18, 80, 71, 88]])
    
    arr.shape
    ---- (5, 7)
    
    将多维数组变形成一维数组
    all_l=arr.reshape((35,))
    all_l
    ---   array([49, 51, 54, 77, 69, 13, 25, 13, 92, 86, 30, 30, 89, 12, 65, 31, 57,
           36, 27, 18, 93, 77, 22, 23, 94, 11, 28, 74, 88,  9, 15, 18, 80, 71,
           88])

    级联

    #就是对多个numpy数据进行横向或者纵向的拼接
    
    #一维,二维,多维数组的级联,实际操作中级联多为二维数组
    np.concatenate((arr,arr),axis=0) #axis=0 列  1表示行
    ---  array([[49, 51, 54, 77, 69, 13, 25],
           [13, 92, 86, 30, 30, 89, 12],
           [65, 31, 57, 36, 27, 18, 93],
           [77, 22, 23, 94, 11, 28, 74],
           [88,  9, 15, 18, 80, 71, 88],
           [49, 51, 54, 77, 69, 13, 25],
           [13, 92, 86, 30, 30, 89, 12],
           [65, 31, 57, 36, 27, 18, 93],
           [77, 22, 23, 94, 11, 28, 74],
           [88,  9, 15, 18, 80, 71, 88]])
    
    #合并照片,将图片变成九宫格图片
    arr_3 = np.concatenate((img_arr,img_arr,img_arr),axis=1)
    arr_9 = np.concatenate((arr_3,arr_3,arr_3),axis=0)
    plt.imshow(arr_9)

    ndarray的聚合操作

    #求和np.sum
    arr.sum(axis=1)
    ---   array([338, 352, 327, 329, 369])
    
    #最大最小值:np.max/ np.min
    同理
    
    #平均值:np.mean()
    同理
    
    #其他聚合操作
    Function Name    NaN-safe Version    Description
    np.sum    np.nansum    Compute sum of elements
    np.prod    np.nanprod    Compute product of elements
    np.mean    np.nanmean    Compute mean of elements
    np.std    np.nanstd    Compute standard deviation
    np.var    np.nanvar    Compute variance
    np.min    np.nanmin    Find minimum value
    np.max    np.nanmax    Find maximum value
    np.argmin    np.nanargmin    Find index of minimum value
    np.argmax    np.nanargmax    Find index of maximum value
    np.median    np.nanmedian    Compute median of elements
    np.percentile    np.nanpercentile    Compute rank-based statistics of elements
    np.any    N/A    Evaluate whether any elements are true
    np.all    N/A    Evaluate whether all elements are true
    np.power 幂运算

    ndarray的排序

    np.sort(arr,axis=0)
    ---  array([[13,  9, 15, 18, 11, 13, 12],
           [49, 22, 23, 30, 27, 18, 25],
           [65, 31, 54, 36, 30, 28, 74],
           [77, 51, 57, 77, 69, 71, 88],
           [88, 92, 86, 94, 80, 89, 93]])

    Pandas

    导入方式

    import pandas as pd
    from pandas import DataFrame,Series
    import numpy as np

    Series

      Series是一种类似与一维数组的对象,由下面两个部分组成:

    • values:一组数据(ndarray类型)
    • index:相关的数据索引标签

    Series的创建

    #两种创建方式:
    #1 由列表或numpy数组创建
    
    #   默认索引为0到N-1的整数型索引
    
    #使用列表创建Series
    Series(data=[1,2,3])
    ---   0    1
    1    2
    2    3
    dtype: int64
    
    #还可以通过设置index参数指定索引
    s = Series(data=[1,2,3],index=['a','b','c'])
    s
    ---   a    1
    b    2
    c    3
    dtype: int64

    Series的索引和切片

    s['c']
    ---   3

    Series的基本概念

    #可以使用s.head(),tail()分别查看前n个和后n个值
    s.tail(2)
    ---  b    2
    c    3
    dtype: int64
    
    #对Series元素进行去重
    s = Series(data=[1,1,2,2,3,4,5,6,6,6,7,6,6,7,8])
    s.unique()
    ---   array([1, 2, 3, 4, 5, 6, 7, 8], dtype=int64)
    
    #当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况
    s1 = Series(data=[1,2,3,4],index=['a','b','c','d'])
    s2 = Series(data=[1,2,3,4],index=['a','b','e','d'])
    s = s1 + s2
    s
    ---   a    2.0
    b    4.0
    c    NaN
    d    8.0
    e    NaN
    dtype: float64
    
    #可以使用pd.isnull(),pd.notnull(),或s.isnull(),notnull()函数检测缺失数据
    s.isnull()
    ---  a    False
    b    False
    c     True
    d    False
    e     True
    dtype: bool
    
    s.notnull()
    ---  a     True
    b     True
    c    False
    d     True
    e    False
    dtype: bool
    
    s[s.notnull()]
    ---  a    2.0
    b    4.0
    d    8.0
    dtype: float64
    
    Series之间的运算
    在运算中自动对齐不同索引的数据
    如果索引不对应,则补NaN

    DataFrame

    DataFrame是一个【表格型】的数据结构。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。

    • 行索引:index
    • 列索引:columns
    • 值:values

    DataFrame的创建

    最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。

    此外,DataFrame会自动加上每一行的索引。

    使用字典创建的DataFrame后,则columns参数将不可被使用。

    同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。

    DataFrame(data=np.random.randint(60,100,size=(3,4)))
    
         0    1    2    3
    0    69    81    60    79
    1    64    60    70    64
    2    87    94    98    98
    
     df = DataFrame(data=np.random.randint(60,100,size=(3,4)),index=['A','B','C'],columns=['a','b','c','d'])
    df
          a    b    c    d
    A    92    67    79    68
    B    84    66    61    66
    C    84    79    66    82
    
    #DataFrame属性:values、columns、index、shape
    
    df.values
    array([[92, 67, 79, 68],
           [84, 66, 61, 66],
           [84, 79, 66, 82]])
    
    df.index
    Index(['A', 'B', 'C'], dtype='object')
    
    df.columns
    Index(['a', 'b', 'c', 'd'], dtype='object')
    
    df.shape
    (3, 4)

    DataFrame的索引

    1.对列进行索引
    
        - 通过类似字典的方式  df['q']
        - 通过属性的方式     df.q
    
     可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
    df = DataFrame(data=np.random.randint(60,100,size=(3,4)),index=['A','B','C'],columns=['a','b','c','d'])
    df
    
         a    b    c    d
    A    75    71    92    98
    B    79    93    86    80
    C    78    87    94    91
    
    #修改列索引
    df.columns = ['a','c','b','d']
    df
    
        a    c    b    d
    A    75    71    92    98
    B    79    93    86    80
    C    78    87    94    91
    
    #获取前两列
    df[['a','c']]
        a    c
    A    75    71
    B    79    93
    C    78    87
    
    2. 对行进行索引
    
    - 使用.loc[]加index来进行行索引
    - 使用.iloc[]加整数来进行行索引
    同样返回一个Series,index为原来的columns
    df
        a    c    b    d
    A    75    71    92    98
    B    79    93    86    80
    C    78    87    94    91
    
    df.iloc[0]
    a    75
    c    71
    b    92
    d    98
    Name: A, dtype: int32
    
    df.loc['A']
    a    75
    c    71
    b    92
    d    98
    Name: A, dtype: int32
    
    df.loc[['A','B']]
        a    c    b    d
    A    75    71    92    98
    B    79    93    86    80
     
    3.对元素索引的方法
    
    - 使用列索引
    - 使用行索引(iloc[3,1] or loc['C','q']) 行索引在前,列索引在后
    
    df.iloc[1,2]
    86
    
    df.loc[['B','C'],'b']
    B    86
    C    94
    Name: b, dtype: int32
    
    #索引表示的是列索引
    #切片表示的是行切片
    df[0:2]
         a    c    b    d
    A    75    71    92    98
    B    79    93    86    80
    
    #在loc和iloc中使用切片(切列) : df.loc['B':'C','丙':'丁']
    df.iloc[:,0:2]
         a    c
    A    75    71
    B    79    93
    C    78    87
    
    df['a']
    A    75
    B    79
    C    78
    Name: a, dtype: int32
    
    - 总结:
        - 索引:
            - 取行:df.loc['A']
            - 取列:df['a']
            - 取元素:df.iloc[1,2]
        - 切片:
            - 切行:df[0:2]
            - 切列:df.iloc[:,0:2]

    DataFrame的运算

    DataFrame之间的运算
    
    同Series一样:
    
    在运算中自动对齐不同索引的数据
    如果索引不对应,则补NaN
    
    df + df
        a    c    b    d
    A    150    142    184    196
    B    158    186    172    160
    C    156    174    188    182

    问题解决

    使用tushare包获取某股票的历史行情数据。

    pip install tushare
    import tushare as ts
    #code=股票代码,start=开始时间,end不写默认到最近时间
    df = ts.get_k_data(code='600519',start='2000-01-01')
    
    #保存到本地目录下
    df.to_csv('./600519.csv')
    
    #将date这一列作为源数据的行索引且将数据类型转成时间类型
    df = pd.read_csv('./600519.csv',index_col='date',parse_dates=['date'])
    df.drop(labels='Unnamed: 0',axis=1,inplace=True)

    输出该股票所有收盘比开盘上涨3%以上的日期。

    #(收盘-开盘)/开盘 >= 0.03
    (df['close'] - df['open']) / df['open'] >= 0.03
    
    #将上述表达式返回的布尔值作为df的行索引:取出了所有符合需求的行数据
    df.loc[(df['close'] - df['open']) / df['open'] >= 0.03]
    
    df.loc[(df['close'] - df['open']) / df['open'] >= 0.03].index
    
    
    DatetimeIndex(['2001-08-27', '2001-08-28', '2001-09-10', '2001-12-21',
                   '2002-01-18', '2002-01-31', '2003-01-14', '2003-10-29',
                   '2004-01-05', '2004-01-14',
                   ...
                   '2019-01-15', '2019-02-11', '2019-03-01', '2019-03-18',
                   '2019-04-10', '2019-04-16', '2019-05-10', '2019-05-15',
                   '2019-06-11', '2019-06-20'],
                  dtype='datetime64[ns]', name='date', length=301, freq=None)

    输出该股票所有开盘比前日收盘跌幅超过2%的日期

    #(开盘 - 前日收盘) / 前日收盘  < -0.02
    (df['open'] - df['close'].shift(1)) / df['close'].shift(1) < -0.02
    
    df.loc[(df['open'] - df['close'].shift(1)) / df['close'].shift(1) < -0.02]
    
    df.loc[(df['open'] - df['close'].shift(1)) / df['close'].shift(1) < -0.02].index
    
    DatetimeIndex(['2001-09-12', '2002-06-26', '2002-12-13', '2004-07-01',
                   '2004-10-29', '2006-08-21', '2006-08-23', '2007-01-25',
                   '2007-02-01', '2007-02-06', '2007-03-19', '2007-05-21',
                   '2007-05-30', '2007-06-05', '2007-07-27', '2007-09-05',
                   '2007-09-10', '2008-03-13', '2008-03-17', '2008-03-25',
                   '2008-03-27', '2008-04-22', '2008-04-23', '2008-04-29',
                   '2008-05-13', '2008-06-10', '2008-06-13', '2008-06-24',
                   '2008-06-27', '2008-08-11', '2008-08-19', '2008-09-23',
                   '2008-10-10', '2008-10-15', '2008-10-16', '2008-10-20',
                   '2008-10-23', '2008-10-27', '2008-11-06', '2008-11-12',
                   '2008-11-20', '2008-11-21', '2008-12-02', '2009-02-27',
                   '2009-03-25', '2009-08-13', '2010-04-26', '2010-04-30',
                   '2011-08-05', '2012-03-27', '2012-08-10', '2012-11-22',
                   '2012-12-04', '2012-12-24', '2013-01-16', '2013-01-25',
                   '2013-09-02', '2014-04-25', '2015-01-19', '2015-05-25',
                   '2015-07-03', '2015-07-08', '2015-07-13', '2015-08-24',
                   '2015-09-02', '2015-09-15', '2017-11-17', '2018-02-06',
                   '2018-02-09', '2018-03-23', '2018-03-28', '2018-07-11',
                   '2018-10-11', '2018-10-24', '2018-10-25', '2018-10-29',
                   '2018-10-30', '2019-05-06', '2019-05-08'],
                  dtype='datetime64[ns]', name='date', freq=None)

    假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?

    #将时间限定到2010-2019
    df = df['2010':'2019']
    
    #数据的重新取样
    df_monthly = df.resample('M').first()
    df_yearly = df.resample('A').last()[:-1]
    
    #求出这些年总共买股票所购买金钱总额
    cost_money = df_monthly['open'].sum()*100
    
    #求出这些年卖出股票的金钱总额加上今年所购买的买个月的股票总和
    recv_monry = df['open'][-1] * 800 + df_yearly['open'].sum()*1200
    
    #用卖出股票的钱减去购买股票的钱
    recv_monry - cost_money
  • 相关阅读:
    LA 3938 动态最大连续和 线段树
    UVA 11235 频繁出现的数值 RMQ
    LA 4329 ping-pong树状数组
    LA 3027 合作网络 并查集
    vue-url传参
    vue打开新页面的几种方式
    父子组件传参
    vue--按钮级别的权限控制+插件的使用
    小程序填坑
    webpack小试牛刀
  • 原文地址:https://www.cnblogs.com/sikuaiqian/p/11342834.html
Copyright © 2011-2022 走看看