Python数据分析的起手式(4)Numpy入门

作者: 鱼心DrFish | 来源:发表于2017-03-15 14:16 被阅读2133次

    本文内容整理自DataCamp课程之 Intro to Python for Data Science.

    本系列将包括以下内容:

    访问 我的github 可下载本文对应的notebook以及练习答案,便于亲手实践。


    注意:本文代码基于Python3版本。如果要在python2中执行,需要先导入_future_模块。

    #仅在Python2中使用
    #from __future__ import division
    #from __future__ import print_function
    

    1. 一维数组

    我们在第2讲提到的列表(list)具有非常强大的功能,但却不能很好满足数据分析的要求:实现高速且大量的数学运算。

    用列表分别记录身高和体重这两组数据,我们尝试一下是否能用它来直接计算BMI指数。

    height = [1.73, 1.68, 1.71, 1.89, 1.79] #身高列表
    weight = [65.4, 59.2, 63.6, 88.4, 68.7] #体重列表
    bmi = weight / height ** 2 #计算BMI指数
    bmi

    `---------------------------------------------------------------------------`
    `TypeError                                 Traceback (most recent call last)`
    `<ipython-input-1-b6ce7d301f86> in <module>()`
    `1 height = [1.73, 1.68, 1.71, 1.89, 1.79]  #身高列表`
    ` 2 weight = [65.4, 59.2, 63.6, 88.4, 68.7]  #体重列表`
    `----> 3 bmi = weight / height ** 2  #计算BMI指数`
    `4 bmi`
    `TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'`
    
    
    以上错误告诉我们,列表不能实现整体的数学运算,这正是它的局限。那么该如何有效解决呢?
    
    Python 中有专门的数值计算基础包 Numpy,它是 Numeric Python 的缩写。Numpy提供的数组(array)可以很好地替代 Python 列表,不仅可以实现整体运算,而且还非常简单快速。
    
    那么就让我们用 Numpy 数组来实现上面列表无法完成的BMI指数计算吧。
    
    
    >```python
    import numpy as np  #导入numpy 包
    np_height = np.array(height)  #创建身高的numpy数组
    np_height
    

    array([ 1.73, 1.68, 1.71, 1.89, 1.79])

    np_weight = np.array(weight) #创建体重的numpy数组
    np_weight

    `array([ 65.4,  59.2,  63.6,  88.4,  68.7])`
    
    
    
    
    >```python
    bmi = np_weight / np_height ** 2  #计算BMI指数
    bmi
    

    array([ 21.85171573, 20.97505669, 21.75028214, 24.7473475 , 21.44127836])

    列表元素可以是任何类型,但是 Numpy 数组元素必须是相同类型。下面的例子说明,如果使用了不同的数据类型,则会被强制转化成同一种。

    np.array([1.0, "is", True])

    `array(['1.0', 'is', 'True'], 
              dtype='<U32')`
    
    
    
    加号 `+` 在列表和 Numpy 数组中的作用也是不一样的。在列表中,加号实现列表的拼接;而在 Numpy 数组中,加号则是进行对应元素的加法运算。
    
    
    >```python
    python_list = [1, 2, 3]
    python_list + python_list
    

    [1, 2, 3, 1, 2, 3]

    numpy_array = np.array([1, 2, 3])
    numpy_array + numpy_array

    `array([2, 4, 6])`
    
    
    
    切片操作,Numpy 数组与 Python 列表类似。
    
    
    >```python
    bmi[1]
    

    20.975056689342409

    bmi[1:4]

    `array([ 20.97505669,  21.75028214,  24.7473475 ])`
    
    
    
    但 Numpy 数组能做的远不止这些,比如要找到bmi大于23的数,该怎么做呢?
    
    
    >```python
    bmi > 23
    

    array([False, False, False, True, False], dtype=bool)

    首先我们得到一个布尔变量组成的数组,然后试着将它放入bmi[ ]中会有什么效果?

    bmi[bmi > 23]

    `array([ 24.7473475])`
    
    
    
    于是我们得到了想要的结果,可见,Numpy 数组是多么强大呀!
    
    #### 练习4-1:
    
    你的第一个 Numpy 数组:棒球运动员的身高数据。
    
    
    ```python
    # 创建棒球运动员的身高列表 baseball
    baseball = [180, 215, 210, 210, 188, 176, 209, 200]
    
    # 导入numpy包
    
    # 用列表baseball创建numpy数组:np_baseball
    
    # 打印np_baseball的数据类型
    
    # 将以厘米为单位的身高转换成以米为单位
    
    # 找出高于2米的运动员身高数据
    
    # 打印输出最后一个棒球运动员的身高
    
    # 打印输出最后两个运动员的身高
    
    

    2. 二维数组

    Numpy 数组不仅限于一维,也可以是多维的。比如创建一个身高、体重的二维数组。

    np_2d = np.array([[1.73, 1.68, 1.71, 1.89, 1.79],
    [65.4, 59.2, 63.6, 88.4, 68.7]])
    np_2d

    `array([[  1.73,   1.68,   1.71,   1.89,   1.79],
               [ 65.4 ,  59.2 ,  63.6 ,  88.4 ,  68.7 ]])`
    
    
    
    
    >```python
    np_2d.shape
    

    (2, 5)

    这是一个2行、5列的二维数组,第一行代表身高,第二行代表体重。索引结构如下图所示:

    Numpy 数组

    了解了索引的结构,就可以进行切片操作了。

    np_2d[0] #选取第1行

    `array([ 1.73,  1.68,  1.71,  1.89,  1.79])`
    
    
    
    
    >```python
    np_2d[0][2] #选取第1行第3列
    

    1.71

    np_2d[0,2] #选取第1行第3列的另一种方法

    `1.71`
    
    
    
    
    >```python
    np_2d[:,1:3] #选取每一行的第2、3列
    

    array([[ 1.68, 1.71], [ 59.2 , 63.6 ]])

    np_2d[1,:] #选取第2行的所有列

    `array([ 65.4,  59.2,  63.6,  88.4,  68.7])`
    
    
    
    另外,二维数组的运算也很有意思,仔细观察下面的示例。
    
    
    >```python
    np_mat = np.array([[1, 2],
                       [3, 4],
                       [5, 6]])
    np_mat * 2
    

    array([[ 2, 4], [ 6, 8], [10, 12]])

    np_mat + np.array([10, 10])

    `array([[11, 12],
            [13, 14],
            [15, 16]])`
    
    
    
    
    >```python
    np_mat + np_mat
    

    array([[ 2, 4], [ 6, 8], [10, 12]])

    练习4-2:

    你的第一个 Numpy 二维数组:棒球运动员的身高、体重数据。

    # 创建二维列表 baseball, 第一列是身高,第二列是体重
    baseball = [[180, 78.4],
                [215, 102.7],
                [210, 98.5],
                [188, 75.2]]
    
    #导入 numpy 基础包
    
    # 用二维列表baseball创建二维数组 np_baseball
    
    # 打印输出 np_baseball 的类型
    
    # 打印输出 np_baseball的shape属性
    
    # 打印输出第3行的数据
    
    # 打印输出第二列体总数据
    
    # 打印输出第4名运动员的身高
    
    

    3. 基础统计

    分析的第一步,是观察了解数据。对于少量数据,也许看一眼就行了,但是对于大量数据,就需要用到统计的知识了。Numpy 中有非常丰富的统计工具,那就让我们一起来看看吧。

    下面的例子中,我们收集到棒球运动员的一组数据,每一行代表一位选手的数据,每一列所代表的是体重、身高、年龄信息。

    sample = np.array([
           [  74.  ,  215.  ,   34.69],
           [  72.  ,  210.  ,   30.78],
           [  72.  ,  210.  ,   35.43],
           [  73.  ,  188.  ,   35.71],
           [  69.  ,  176.  ,   29.39],
           [  69.  ,  209.  ,   30.77],
           [  71.  ,  200.  ,   35.07],
           [  76.  ,  231.  ,   30.19],
           [  71.  ,  180.  ,   27.05],
           [  73.  ,  188.  ,   23.88],
           [  73.  ,  180.  ,   26.96],
           [  74.  ,  185.  ,   23.29],
           [  74.  ,  160.  ,   26.11],
           [  69.  ,  180.  ,   27.55],
           [  70.  ,  185.  ,   34.27],
           [  73.  ,  189.  ,   27.99],
           [  75.  ,  185.  ,   22.38],
           [  78.  ,  219.  ,   22.89],
           [  79.  ,  230.  ,   25.76],
           [  76.  ,  205.  ,   36.33]])
    

    首先,用切片的方法得到运动员的身高数据。

    height = sample[:,1]
    height

    `array([ 215.,  210.,  210.,  188.,  176.,  209.,  200.,  231.,  180.,
                188.,  180.,  185.,  160.,  180.,  185.,  189.,  185.,  219.,
                230.,  205.])`
    
    
    
    使用 `np.mean()` 函数计算身高的平均值:
    
    
    >```python
    np.mean(height)
    

    196.25

    使用 np.median() 函数计算身高的中位数:

    np.median(height)

    `188.5`
    
    
    
    使用 `np.std()` 函数计算身高的标准差:
    
    
    >```python
    np.std(height)
    

    18.616860637604827

    使用 np.corrcoef() 函数计算体重和身高的相关系数:

    np.corrcoef(sample[:,0], sample[:,1])

    `array([[ 1.        ,  0.50671793],
            [ 0.50671793,  1.        ]])`
    
    
    
    使用 Numpy 还可以进行统计模拟,生成随机数或符合特定分布的数值。比如,下面的代码生成了一组100个符合正态分布的数值,均值是1.75,标准差是0.2。
    
    
    ```python
    data = np.round(np.random.normal(1.75, 0.20, size=100), 2)
    

    sum()sort()这类的函数,Numpy 和 Python 中都有,那么它们的区别在哪里呢?关键在于 Numpy 中的计算速度更快,因为 Numpy 是专门针对数值计算的,而 Python 还要考虑其他数据类型。

    sum(height)

    `3925.0`
    
    
    
    
    >```python
    np.sum(height)
    

    3925.0

    练习4-3:

    综合练习:找出足球运动中守门员和其他运动员的身高的中位数。

    # 创建足球运动员的位置和对应的身高数据
    positions = ['GK', 'M', 'A', 'D', 'M', 'D', 'M', 'M', 'M', 'A', 'M', 'M', 'A', 'A', 'A', 'M', 'D', 'A', 'D', 'M', 'GK', 'D', 'D', 'M', 'M', 'M', 'M', 'D', 'M', 'GK']
    heights = [191, 184, 185, 180, 181, 187, 170, 179, 183, 186, 185, 170, 187, 183, 173, 188, 183, 180, 188, 175, 193, 180, 185, 170, 183, 173, 185, 185, 168, 190]
    
    # 导入numpy包
    import numpy as np
    
    # 将列表 positions 和 heights 分别转化成numpy数组: np_positions, np_heights
    
    # 将守门员的身高数据存入变量 gk_heights, 守门员对应的位置编码是’GK‘
    gk_heights = 
    
    # 将守门员之外的其他运动员的身高数据存入变量 other_heights
    other_heights = 
    
    # 打印输出守门员身高的中位数,替换代码中的'None'
    print("Median height of goalkeepers: " + str(None))
    
    # 打印输出其他运动员身高的中位数,替换代码中的'None'
    print("Median height of other players: " + str(None))
    

    补充:

    关于 我的github 中文件下载的方式:

    • 如果下载单个文件,点击所要下载的文件,在新打开的页面中找到右上方的 raw 按钮,右击另存为即可。另外文件名需要删除后缀 .txt,而保留原始格式后缀,如 .ipynb 。

    • 如果打包下载,回到github库的根目录中,点击右上方绿色的 Clone and download 按钮,选择 Download ZIP 即可。

    本文使用Jupyter notebook 编写,关于它的说明和安装方法,可以参考我之前的两篇文章。

    相关文章

      网友评论

      • 鬼宇书生:将守门员的身高数据存入变量 gk_heights, 守门员对应的位置编码是’GK, 将两组数据存放到一个列表之后,怎么读取编码是‘GK’ 的身高呢?
        鱼心DrFish:@鬼宇书生 这里面有个小trick,详情可以参考我在github中给的答案。
      • 鬼宇书生:照着做了下,特别实用,感谢
        鱼心DrFish:@鬼宇书生 赞实践!

      本文标题:Python数据分析的起手式(4)Numpy入门

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