一、Numpy 介绍
Numpy (Numerical Python) 是一个开源的 Python 科学计算库,用于快速处理任意维度的数组。 Numpy 支持常见的数组和矩阵操作。
对于同样的数值计算任务,使用 Numpy 比直接使用 Python 要简洁的多。
Numpy 使用 ndarray 对象来处理多维数组,该对象是一个快速而灵活的大数据容器。
二、Ndarray 介绍
NumPy 提供了一个N维数组类型 ndarray ,它描述了相同类“items” 的集合。
要存储八个同学的成绩
用 ndarray 进行存储:
import numpy as np
score=np.array([[80, 89, 86, 67, 79] ,
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74] ,
[91, 91, 90, 67, 69] ,
[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84] ,
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]])
print(type(score),score)
返回结果:
<class 'numpy.ndarray'> [[80 89 86 67 79]
[78 97 89 67 81]
[90 94 78 67 74]
[91 91 90 67 69]
[76 87 75 67 86]
[70 79 84 67 84]
[94 92 93 67 64]
[86 85 83 67 80]]
三、Ndarray 与 Python 原生 list 运算效率对比
在这里我们通过一段代码运行来体会到 ndarray 的好处
import random
import time
import numpy as np
a = []
for i in range(100000000):
a.append(random.random())
%time sum1=sum(a)
b=np.array(a)
%time sum2=np.sum(b)
输出结果为:
CPU times: user 1.82 s, sys: 17.8 s, total: 19.6 s
Wall time: 57.9 s
CPU times: user 189 ms, sys: 606 ms, total: 794 ms
Wall time: 2.04 s
从中我们看到 ndarray 的计算速度要快很多,节约了时间(57.9s降低到了2.04s)。
机器学习的最大特点就是大量的数据运算,那么如果没有一个快速的解决方案,那可能现在 python 也在机器学习领域达不到好的效果。
Numpy 专门针对 ndarray 的操作和运算进行了设计,所以数组的存储效率和输入输出性能远优于 Python 中的嵌套列表,数组越大,Numpy 的优势就越明显。
四、Ndarray 的优势
1.储存风格
从图中我们可以看出 ndarray 在存储数据的时候,数据与数据的地址都是连续的,这样就给使得批量操作数组元素时速度更快。
这是因为 ndarray 中的所有元素的类型都是相同的,而 Python 列表中的元素类型是任意的,所以 ndarray 在存储元素时内存可以连续,而 python 原生 list 只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面 Numpy 的 ndarray 不及 Python 原生list,但在科学计算中, Numpy 的 ndarray 就可以省掉很多循环语句,代码使用方面比 Python 原生 list 简单的多。
2.并行化运算
ndarray 支持并行化运算(向量化运算)
3.底层语言
Numpy 底层使用 C 语言编写,内部解除了 GIL(全局解释器锁),其对数组的操作速度不受 Python 解释器的限制,效率远高于纯 Python 代码。
五,numpy的属性和类型
ndarray 的属性
数组属性反映了数组本身固有的信息。
ndarray.shape 数组维度的元组
ndarray.ndim 数组维数
ndarray.size 数组中的元素数量
ndarray.itemsize 一个数组元素的长度(字节)
ndarray.dtype 数组元素的类型
a=np.array([[1, 2, 3],[4, 5, 6]],dtype=np.float32)
b=np.array([1,2,3,4])
c=np.array([[[1,2,3],[4,5,6,]],[[1,2,3],[4,5,6]]])
print(a.shape)
print(b.shape)
print(c.shape)
结果如下:
(2, 3)
(4,)
(2, 2, 3)
那么,现在的a,b,c数组分别是几维数组呢?有多少个中括号就是几维的数组哦,因此,a是二维数组,b是一维数组,c是三维数组。
np.bool | 用一个字节存储的布尔类型(True 或 False) | ‘b' |
np.int8 |
一个字节大小,-128至127 | 'i' |
np.int16 | 整数,-32768至32767 | i2' |
np.int32 | 整数,-231至232-1 | ‘i4' |
np.int64 | 整数,-263至263-1 | i8’ |
np.uint8 | 无符号整数,0至255 | 'u' |
np.uint16 | 无符号整数,0至65535 | 'u2' |
np.uint32 | 无符号整数,0至2**32-1 | 'u4' |
np.uint64 | 无符号整数,0至2**64-1 | 'u8' |
np.float16 | 半精度浮点数:16位,正负号1位,指数5位,精度10位 | ‘f2’ |
np.float32 | 单精度浮点数:32位,正负号1位,指数8位,精度23位 | ‘f4’ |
np.float64 | 双精度浮点数:64位,正负号1位,指数11位,精度52位 | ‘f8’ |
np.complex128 |
复数,分别用两个64位浮点数 表示实部和虚部 |
'c16' |
np.object_ | python 对象 | ‘O’ |
np.string_ | 字符串 | ’S’ |
np.unicode_ | unicode 类型 | ’U’ |
建立一个数组,名称为d,指定类型为int16:
d=np.array([1,2,3,32767],dtype=np.int16)
print(d.dtype)
print(d)
也可以这样指定类型:
d=np.array([1,2,3,32800],dtype="i2")
print(d.dtype)
print(d)
但32800已经超过int16的范围了,因此,结果是错误的哦,结果如下:
int16
[ 1 2 3 -32736]
修改i2为i8就可以正常显示啦。