Numpy基础科学库极简使用说明

作者:欧新宇(Xinyu OU)

本文档所展示的测试结果,均运行于:Intel Core i7-7700K CPU 4.2GHz

1. Why Numpy?

  • numpy是"Numerical Python"的简称。
  • numpy提供了一个高性能的多维数组对象ndarray(N Dimension Array),以及大量的库函数和操作,可以帮助程序员轻松地进行数值计算。
  • 原生python语言执行速度很慢,C执行500次,python差不多只能执行一次,但是python语法比其它编程语言要简单的多得多。因此我们既想要某一个编程语言执行速快,同时还编程简单。最终python通过集成C和C++,最终解决这个问题,也就是说:底层运行的是C和C++的代码,但是上层使用的是python语言去写的。这就是我们为什么都喜欢使用"numpy库"的原因。
  • numpy作为很多的用来做数据挖掘,数据分析,人工智能相关的技术组件的底层实现。像SciPy、Matplotlib、Scikit-learn在一定程度上,都需要依赖numpy。

2. Numpy的套路

Numpy的核心是什么?=====> ndarry数组,也就是说numpy最重要的数据结构就是称为ndarray的n-dim数组,它由两个部分构成: 1). 元数组部分:存储着当前ndarray对象的描述信息; 2). 数据部分:存储着当前ndarry对象的真实数据。

3. Numpy的基本属性

载入numpy

In [26]:
import numpy as np

显示数组

In [19]:
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

display(x)

print("x = \n{}".format(x))
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
x = 
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

数组的形状

In [27]:
x.shape
Out[27]:
(3, 4)

数组的大小

In [21]:
x.size
Out[21]:
12

数组的类型

In [22]:
x.dtype
Out[22]:
dtype('int32')

数组的维数

In [12]:
x.ndim
Out[12]:
2

4. ndarray数组和list列表的简单的对比

In [83]:
x = list(range(1000000))
%timeit [i**2 for i in x]
338 ms ± 5.24 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [84]:
import numpy as np
y = np.arange(1000000)
%timeit y**2
1.95 ms ± 55.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

可以看到numpy的执行效率要远优于python内置的list。

5. 关于维度

In [81]:
import numpy as np

# 一维数组
a = np.array([1, 2, 3, 4, 5, 6])
print("我是一个维度为{}的一维数组:\n{}".format(a.ndim, a))

# 二维数组
b = np.array([[1, 2, 3], [4, 5, 6]])
print("我是一个维度为{}的二维数组:\n{}".format(b.ndim, b))

# 三维数组
c = np.array([[[1,2,3], [4,5,6],[7,8,9]],[[1,2,3], [4,5,6],[7,8,9]]])
print('我是一个维度为{}的三维数组:\n{}'.format(c.ndim, c))
我是一个维度为1的一维数组:
[1 2 3 4 5 6]
我是一个维度为2的二维数组:
[[1 2 3]
 [4 5 6]]
我是一个维度为3的三维数组:
[[[1 2 3]
  [4 5 6]
  [7 8 9]]

 [[1 2 3]
  [4 5 6]
  [7 8 9]]]
In [78]:
# 分别从一维、二维、三维数组中获取元素值为 "6" 的方法
import numpy as np
print('我是一维数组的{}'.format(a[5]))

print('我是二维数组的{}'.format(b[1][2]))

print('我是三维数组的{}'.format(c[0][1][2]))
我是一维数组的6
我是二维数组的6
我是三维数组的6

6. 创建数组的几种不同方式

利用array()函数创建数组

In [86]:
import numpy as np

array1 = [1,2,3]
a = np.array(array1)
display(a)

array2 = [[1,2,3],[4,5,6]]
b = np.array(array2)
display(b)
array([1, 2, 3])
array([[1, 2, 3],
       [4, 5, 6]])

结论如下:

  • np.array(参数)函数,参数给了什么样式的数据,就构建什么样式的ndarray数组;你给我一个一维列表,我就构建一个一维数组;你给我一个二维列表,我就构建一个二维数组;
  • 什么是二维列表?每个元素都是一个一维列表的列表,就是一个二维列表;
  • 如果我构建了一个二维列表,那么这个二维列表中的每个元素就都是一个一维列表;
  • 在numpy中,一维数组又叫做"向量";二维数组又叫做"矩阵";

利用范围函数arange()生成数组,此处对比range()函数

注意:arange()函数的步长,可以是浮点数,但是range()函数的步长,不能是浮点数

In [94]:
# 正向递增
list1 = list(range(1,10,2))
display(list1)
[1, 3, 5, 7, 9]
In [1]:
# 浮点型正向递增
list2 = list(range(1,10,0.5))
display(list2)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-e8ab0069a4e6> in <module>
      1 # 浮点型正向递增
----> 2 list2 = list(range(1,10,0.5))
      3 display(list2)

TypeError: 'float' object cannot be interpreted as an integer
In [96]:
# 反向递减
list3 = list(range(10,1,-2))
display(list3)
[10, 8, 6, 4, 2]
In [97]:
# 正向递增
array1 = np.arange(1,10,2)
display(array1)
# 浮点型正向递增
array2 = np.arange(1,10,0.5)
display(array2)
# 反向递减
array3 = np.arange(10,1,-2)
display(array3)
array([1, 3, 5, 7, 9])
array([1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. , 6.5, 7. ,
       7.5, 8. , 8.5, 9. , 9.5])
array([10,  8,  6,  4,  2])

生成指定常用函数

  • np.zeros((x,y)):生成一个x行y列的,元素都是0的二维数组;
  • np.ones((x,y)):生成一个x行y列的,元素都是1的二维数组;
  • np.full((x,y),value):生成一个x行y列的,元素都是value的二维数组,其中这个value值可以是整数(正整数,0,负整数)或者小数;
In [98]:
array1 = np.zeros((3,4))
display(array1)

array2 = np.ones((3,4))
display(array2)

array1 = np.full((3,4),1.2)
display(array3)
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
array([10,  8,  6,  4,  2])

注意:此处以创建二维数组为例,你传入一个数字,就可以创建一维数组;你传入三个数字,就可以创建三维数组,可以自己下去试一试。

创建单位矩阵和对角矩阵

In [100]:
## np.eye(x)和 np.identity(x)
array1 = np.eye(3)
display(array1)

array2 = np.identity(4)
display(array2)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]])

创建等差数列数组

  • np.arange(start,stop,step)第三个参数指的是元素步长;
  • np.linspace(start,stop,num)第三个参数指的是元素个数;

np.arange()取不到最大的那个值stop,np.linspace()默认可以取到最大值stop;

In [101]:
array1 = np.arange(1,15,3)
display(array1)
display(array1.dtype)

array2 = np.linspace(1,15,3)
display(array2)
display(array2.dtype)
array([ 1,  4,  7, 10, 13])
dtype('int32')
array([ 1.,  8., 15.])
dtype('float64')

通过自定义函数创建数组

In [102]:
## 定义一个函数
def f(x, y):
    return x * 2 + y + 1

## 从一个函数生成一个二维数组;
b = np.fromfunction(f, (3,3), dtype=np.int32)
display(b)

## 在这个函数,f函数要接收的参数,就是当前元素的坐标;
## 0行0列,传入的就是x=0,y=0;
## 0行1列,传入的就是x=0,y=1;
## 3行2列,传入的就是x=3,y=2;
array([[1, 2, 3],
       [3, 4, 5],
       [5, 6, 7]])