Python 数据科学 (1)——NumPy(1.Arrays 基础篇)

本贴最后更新于 1830 天前,其中的信息可能已经时移世改

Python 数据科学中有两个很重要的扩展程序库,numpy 和 pandas。本文将首先介绍 numpy 的基本使用,本文假设你已经具有了一定的 python 基础,故而不会特别介绍 python 的语法。

NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。这种工具可用来存储和处理大型矩阵,比 Python 自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix))。numpy 包含以下特性:

  1. 一个强大的 N 维数组对象 Array;
  2. 比较成熟的(广播)函数库;
  3. 用于整合 C/C++ 和 Fortran 代码的工具包;
  4. 实用的线性代数、傅里叶变换和随机数生成函数。

numpy 和稀疏矩阵运算包 scipy 配合使用更加方便。

在你的计算机上安装最简单的方式是 pip install numpy,对于 python3 可能需使用 pip3,前提是你已经安装了 python 环境和对应的 pip 工具。本文强烈建议学习者使用 IPython 交互式 shell 其在命令行下有强大的提示功能,对应安装。或者使用可直接运行 python 代码的 Jupyter 交互式笔记本,对应安装。本文使用 ipython 工具作为演示,只要在 shell 里输入 ipython 即可,如下所示:

~$ ipython
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

紧接着,我们只需输入 import numpy as np 即可导入 numpy 模块。

numpy 数组

python 的整数不单纯

由于 python 本身的动态特性,不需要像静态语言那般需要首先声明变量和规定其对应的变量类型(如在 c 中,使用变量 i 之前需要声明 int i = 0;),这意味着我们可给同一变量赋予不同的值(如 x = 0; x = 'python',两次赋值都是合法的)。我们知道标准的 python 实现是用 c 语言编写的,python 中每个变量都是一个巧妙封装的 c 结构体变量。所以,就一个具体的长整型来说不是一个单纯的长整型,其在 c 中对应者结构体:

struct  _longobject  { 
    long  ob_refcnt ; //一个帮助Python静默处理内存分配和释放的引用计数
    PyTypeObject  * ob_type ; //它编码变量的类型
    size_t  ob_size ; //指定以下数据成员的大小
    long  ob_digit [ 1 ]; //它包含我们期望Python变量表示的实际整数值。
};

这意味着 python 的数据结构天然的比 c 语言或其他相似的静态语言数据结构要多出许多而外的开销。由此,也可以推断出,python 的 l 列表也不是单纯的列表,二是索引了其他对象的列表。所以,即使我们输入 [True, "2", 3.0, 4] 也是合法的。这有点类似于 c#或 java 中的 var ls = new List<object>{true, "2", 3.0, 4};,同样的在 c 中空指针 void *p; 也是个万能的存在,你可以用它指向任何对象。在灵活性方面无可挑剔,但是就资源和效率方面来说实在让人感到堪忧。作为固定类型的 numpy 数组可以解决我们的担忧。

Python 中的固定类型数组

1. array

array 在 python3.3 以后才合法,。在 ipython 中,输入以下内容:

In [1]: import array                                                           
In [2]: L = list(range(10)) 
In [3]: A = array.array('i', L)     # i是类型标识符,用于指定数组为整性     
In [4]: A                                                                      
Out[4]: array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

2. numpy

在 ipython 中,使用 np.array 即可创建数组

In [1]: import numpy as np 
In [2]: np.array([1, 4, 2, 5, 3])                                              
Out[2]: array([1, 4, 2, 5, 3])

可以使用 dtpye 来指定具体类型 np.array([1, 2, 3, 4], dtype='float32')。作为重点:numpy 数组和普通 python 数组不同,它可以是多维的,这意味着它可以用来进行矩阵运算。

In [1]: np.array([range(i, i + 3) for i in [2, 4, 6]])                         
Out[1]: 
array([[2, 3, 4],
       [4, 5, 6],
       [6, 7, 8]])

使用 numpy 原生借口创建大型数组,效率会有更好的支持。

创建初始值为 0 的数组:

In [1]: np.zeros(10, dtype=int)                                                
Out[1]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

创建初始值为 1 的多维数组:

In [1]: np.ones((3, 5), dtype=float)                                           
Out[1]: 
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

创建自定义初始值的多维数组:

In [1]: np.full((3, 5), 3.14)                                                  
Out[1]: 
array([[ 3.14,  3.14,  3.14,  3.14,  3.14],
       [ 3.14,  3.14,  3.14,  3.14,  3.14],
       [ 3.14,  3.14,  3.14,  3.14,  3.14]])

也可以像普通数组那样创建线性序列:

In [1]: np.arange(0, 20, 2)                                                    
Out[1]: array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])

创建均分序列:

In [1]: np.linspace(0, 1, 5)                                                   
Out[1]: array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ])

创建随机数组:

In [1]: np.random.random((3, 3))                                               
Out[1]: 
array([[ 0.68306984,  0.88296926,  0.25726865],
       [ 0.58618715,  0.64491405,  0.79462547],
       [ 0.64385013,  0.95813808,  0.37981454]])

创建正态分布的数组:

In [1]: np.random.normal(0, 1, (3, 3))                                         
Out[1]: 
array([[ 1.19851917,  0.72038886, -1.42196799],
       [ 1.26959716,  3.40746064, -1.18897577],
       [ 0.98618923,  2.2003404 , -0.25561642]])

创建整形随机数组:

In [1]: np.random.randint(0, 10, (3, 3))                                       
Out[1]: 
array([[1, 3, 1],
       [8, 2, 9],
       [3, 8, 6]])

创建单位矩阵:

In [1]: np.eye(3)                                                              
Out[1]: 
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])

创建空数组(初始值为内存值,即只创建,但不改变内存分配得到的值):

In [31]: np.empty(3)                                                            
Out[31]: array([ 1.,  1.,  1.])

numpy 中的标准数据类型

数据类型 描述
bool_ 存储为字节的布尔值(True 或 False)
int_ 默认整数类型(与 C 相同 long;通常为 int64int32
intc 与 C 相同 int(通常 int32int64
intp 用于索引的整数(与 C 相同 ssize_t;通常为 int32 或者 int64
int8 字节(-128 到 127)
int16 整数(-32768 至 32767)
int32 整数(-2147483648 至 2147483647)
int64 整数(-9223372036854775808 至 9223372036854775807)
uint8 无符号整数(0 到 255)
uint16 无符号整数(0 到 65535)
uint32 无符号整数(0 到 4294967295)
uint64 无符号整数(0 到 18446744073709551615)
float_ 简写 float64
float16 半精度浮点数:符号位,5 位指数,10 位尾数
float32 单精度浮点数:符号位,8 位指数,23 位尾数
float64 双精度浮点数:符号位,11 位指数,52 位尾数
complex_ 简写 complex128
complex64 复数,由两个 32 位浮点数表示
complex128 复数,由两个 64 位浮点数表示

我们可以这样使用 np.zeros(10, dtype=np.int16) 或者 np.zeros(10, dtype='int16')。当然,除此之外,也可以自定义更多高级的数据类型,例如指定其所占的字节数大小,有兴趣或者需要的请自行查阅。

  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    536 引用 • 672 回帖
  • numpy
    9 引用 • 1 关注
  • 数据科学
    7 引用 • 1 关注
1 操作
hsxian 在 2019-04-22 09:49:27 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...