前言
NumPy是用Python进行科学计算的基础库。NumPy以一个强大的n维数组对象为中心,它还包含有用的线性代数、傅立叶变换和随机数函数。
1.创建数组
import numpy as np
np.zeros:函数的作用是:创建一个包含任意数量零的数组
创建一个一维数组(零矩阵)
np.zeros(5)
创建一个二维数组(3x4的零矩阵)
np.zeros((3,4))
在NumPy中,每个维度称为一个轴,轴的数量称为秩。
例如,上面的3x4矩阵是一个秩为2的数组(它是二维的)。
第一个轴的长度是3,第二个轴的长度是4。
数组的轴长度列表称为数组的形状。
例如,上述矩阵的形状为(3,4)。
秩等于形状的长度。
数组的大小是元素的总数,它是所有轴长度的乘积。3 * 4 = 12
a = np.zeros((3,4))
print('数据的形状:',a.shape)
print('数据的秩/维度:',a.ndim)#等同len(a.shape)
print('数据的元素总数:',a.size)
n维数组
还可以创建任意秩的n维数组。例如,下面是一个3D数组(rank=3),形状为(2,3,4)
np.zeros((2,3,4))
np.ones:
下面创建一个满是1的3x4矩阵:
np.ones((3,4))
np.full
用给定值,初始化一个给定形状的数组。以下是一个充满π的3x4矩阵。
np.full((3,4), np.pi)
np.empty
一个未初始化的2x3数组(其内容是不可预测的,因为它是当时内存中的任何内容):
np.empty((2,3))
np.array
可以使用常规python数组初始化narray。只需调用数组函数:
np.array([[1,2,3,4], [10, 20, 30, 40]])
np.arange
可以使用NumPy的range函数创建一个narray,它类似于python的内置range函数:
np.arange(1, 5)
还可以提供一个step参数:
np.arange(1, 5, 0.5)
np.linspace
在处理浮点数时,通常最好使用linspace函数而不是arrange。linspace函数返回一个数组,其中包含在两个值之间均匀分布的特定数量的点(注意包括最大值,与range相反):
print(np.linspace(0, 5/3, 6))
np.rand 和np.randn
NumPy的random模块中有许多函数可用于创建用随机值初始化的ndarray。
例如,下面是一个3x4矩阵,用0到1之间的随机浮点数初始化(均匀分布):
np.random.rand(3,4)
下面是一个3x4矩阵,包含随机浮点数,采样自均值为0,方差为1的单变量正态分布(高斯分布):
np.random.randn(3,4)
这里进行画图,做出直观展示
%matplotlib inline
import matplotlib.pyplot as plt
plt.hist(np.random.rand(100000), density=True, bins=100, histtype="step", color="blue", label="rand")
plt.hist(np.random.randn(100000), density=True, bins=100, histtype="step", color="red", label="randn")
plt.axis([-2.5, 2.5, 0, 1.1])
plt.legend(loc = "upper left")
plt.title("Random distributions")
plt.xlabel("Value")
plt.ylabel("Density")
plt.show()
np.fromfunction
也可以使用函数初始化narray:
def my_function(z, y, x):
return x + 10 * y + 100 * z
np.fromfunction(my_function, (3, 2, 10))
NumPy首先创建三个ndarray(每个维度一个),形状为(3,2,10)。每个数组的值等于沿特定轴的坐标。
表达式x + 10 * y + 100 * z 中的项x, y和z实际上是数组。函数my_function只被调用一次,避免了每个元素调用一次,使得初始化非常有效。
2.数组的数据类型
dtype
NumPy的ndarray高效,部分原因是它们的所有元素必须具有相同的类型。可以通过查看dtype属性来检查数据类型:
c = np.arange(1, 5)
print(c.dtype, c)
c = np.arange(1.0, 5.0)
print(c.dtype, c)
还可以通过设置dtype参数在创建数组时显式设置它:
d = np.arange(1, 5, dtype=np.complex64)
print(d.dtype, d)
常见的数据类型还包括int8、int16、int32、int64、uint8|16|32|64、float16|32|64和complex64|128。
itemsize
itemsize属性返回项的大小(以字节为单位):
e = np.arange(1, 5, dtype=np.complex64)
e.itemsize #8
3.重塑数组
更改narray的形状可以设置其shape属性。但是,数组的大小必须保持不变。
g = np.arange(24)
print(g)
print("Rank:", g.ndim)
g.shape = (6, 4)
print(g)
print("Rank:", g.ndim)
g.shape = (2, 3, 4)
print(g)
print("Rank:", g.ndim)
reshape
reshape函数返回一个指向相同数据的新的narray对象。这意味着修改一个数组也会修改另一个数组;
g2 = g.reshape(4,6)
print(g2)
print("Rank:", g2.ndim)
ravel
ravel函数返回一个新的一维narray,它也指向相同的数据:
g.ravel()
4.算术运算
所有常用的算术运算符(+,-,*,/,//,**等)都可以与ndarray一起使用。
a = np.array([14, 23, 32, 41])
b = np.array([5, 4, 3, 2])
print("a + b =", a + b)
print("a - b =", a - b)
print("a * b =", a * b)
print("a / b =", a / b)
print("a // b =", a // b)
print("a % b =", a % b)
print("a ** b =", a ** b)
5.条件运算符
条件运算符也适用于元素:
m = np.array([20, -5, 30, 40])
m < [15, 16, 35, 36]
m < 25 # 等价于 m < [25, 25, 25, 25]
m[m < 25]
6.数学和统计函数
许多数学和统计函数可用于ndarray。
例如:求均值,最小值,最大值,总值等
a = np.array([[-2.5, 3.1, 7], [10, 11, 12]])
for func in (a.mean, a.min, a.max, a.sum, a.prod, a.std, a.var):
print(func.__name__, "=", func())
NumPy还提供了快速的元素函数,称为通用函数或ufunc。它们是简单函数的矢量化包装。例如,square返回一个新的ndarray,是每个元素的平方:
a = np.array([[-2.5, 3.1, 7], [10, 11, 12]])
np.square(a)
print("Original ndarray")
print(a)
for func in (np.abs, np.sqrt, np.exp, np.log, np.sign, np.ceil, np.modf, np.isnan, np.cos):
print("\n", func.__name__)
print(func(a))
还有许多二进制ufuncs,它们按元素方式应用于两个数组。
a = np.array([1, -2, 3, 4])
b = np.array([2, 8, -1, 7])
np.add(a, b) # 等价于 a + b
np.greater(a, b) # 等价于 a > b
np.maximum(a, b)
np.copysign(a, b)
7.数组索引\数组切片
一维数组
a = np.array([1, 5, 3, 19, 13, 7, 3])
a[3] #19
a[2:5]
a[2:-1]
a[:2]
a[2::2]
a[::-1]
多维数组
多维数组可以以类似的方式访问,通过为每个轴提供一个索引或切片,用逗号分隔:
b = np.arange(48).reshape(4, 12)
b
b[1, 2] # row 1, col 2 是14
b[1, :] # 第二行
b[:, 1] # 第二列
b[1:3, :] #第二至三行
b[(0,2), 2:5] # 第一行,和第三行, 列3-4
8.叠加数组
将不同的数组堆叠在一起通常很有用。NumPy提供了几个函数来实现这一点。
q1 = np.full((3,4), 1.0)
q2 = np.full((4,4), 2.0)
q3 = np.full((3,4), 3.0)
vstack
使用vstack垂直堆叠它们:
q4 = np.vstack((q1, q2, q3))
q4
hstack
可以使用hstack来水平堆叠数组:
q5 = np.hstack((q1, q3))
q5
concatenate
concatenate函数沿着任何给定的现有轴堆叠数组。
q7 = np.concatenate((q1, q2, q3), axis=0) # 等价于 vstack ,当axis=1时,等价于hstack
q7
stack
stack函数沿着一个新的轴堆叠数组。所有数组必须具有相同的形状
q8 = np.stack((q1, q3))
q8
9.数组分割
分割是堆叠的对立面。例如,使用vsplit函数来垂直分割矩阵。
首先,创建一个6x4矩阵:
r = np.arange(24).reshape(6,4)
r
r1, r2, r3 = np.vsplit(r, 3)
还有一个split函数,可以沿着任何给定的轴拆分数组。调用vsplit相当于调用轴为0的split。还有一个hsplit函数,相当于用axis=1调用split:
r4, r5 = np.hsplit(r, 2)