Numpy自学笔记(一)
更加详细的学习资料请见:https://www.numpy.org.cn/user/
一.基础知识
NumPy的数组类被调用ndarray。它也被别名所知 array。请注意,numpy.array这与标准Python库类不同array.array,后者只处理一维数组并提供较少的功能。ndarray对象更重要的属性是:
import numpy as np
a = np.arange(15).reshape(3,5)
a
结果:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
import numpy as np
a = np.arange(15).reshape(3,5)
a
a.shape #数组的维度,整数元组;对于一个n行m列的矩阵,shape将是(n,m)
a.ndim #ndarray.shape元组的长度就是rank或者维度的个数ndim
a.dtype #ndarray.dtype 一个描述数组中元素类型的对象。可以使用标准的Python类型创建或指定dtype。另外NumPy提供它自己的类型。例如numpy.int32、numpy.int16和numpy.float64
a.dtype.name
a.itemsize # ndarray.itemsize = ndarray.dtype.itemsize 数组中每个元素的字节大小
a.dtype.itemsize # 元素为 float64 类型的数组的 itemsize 为8(=64/8),
# 而 complex32 类型的数组的 itemsize 为4(=32/8)
a.dtype.itemsize
a.size #ndarray.size - 数组元素的总数。这等于 shape 的元素的乘积。
type(a) #返回a的类型
a.data #ndarray.data - 该缓冲区包含数组的实际元素。通常,我们不需要使用此属性,因为我们将使用索引访问数组中的元素。
help(np.array) #help() 可以调出帮助
二.数组的创建
1.数组创建
a = np.array([1,2,4])
print(a)
print(a.dtype)
结果:
[1 2 4]
int32
b = np.array([1.2,2.3,5.8])
print(b)
print(b.dtype)
结果:
[1.2 2.3 5.8]
float64
注意1:调用np.array(a) a不能为多个数字,可以是单个数字的列表类型
a = np.array(1,2,3,4) #错
a = np.array([1,2,3,4]) #对
注意2: array可以将序列的序列转化成二维数组,将序列的序列的序列转化为三维数组
b = np.array([(1.5,2,3),(4,5,6)])
print(b)
print(b.ndim)
结果:
array([[1.5, 2. , 3. ],
[4. , 5. , 6. ]])
2
注意3:创建时显示指定数组类型
c = np.array([[1,2],[3,4]],dtype = complex) #指定类型为复数
c
结果:
array([[1.+0.j, 2.+0.j],
[3.+0.j, 4.+0.j]])
2.几个特殊的数组
- np.zeros((n,m)) 创建一个由0组成的数组
- np.ones((n,m,p),dtype = np.int16) 创建一个完整的数组
- np.empty((n,m)) 创建一个默认数组,内容随机,取决于内存状态,默认 dtype = float64
np.zeros((3,4)) # 默认dtype = np.float64,生成一个3*4的元素全是0的数组
np.ones((2,4,3),dtype = np.int16) #生成一个(2,4,3)的元素全为1的数组
np.empty((2,4)) #创建一个默认数组,类型默认为float64
3.创建数字数组的另一个方法类似于
- range(a,b,c) 生成从a到b [a,b) 步长为c的列表
- np.arange(a,b,c) 生成从a到b [a,b) 步长为c的数组而不是列表
- np.linspace(a,b,c) 生成[a,b]的c个数 数组
np.arange(10,20,2)
np.arange(0,2,0.5)
当arange与浮点参数一起使用时,由于有限的浮点精度,通常不可能预测所获得的元素的数量。 出于这个原因,通常最好使用linspace函数来接收我们想要的元素数量的函数,而不是步长。
np.linspace(0,2,9) #返回从0到2的9个等距浮点数
结果:
array([0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])
一个例子:
from numpy import pi
x = np.linspace(0,2*pi,10)
f = np.sin(x)
f
三.数组打印
打印数组时,NumPy以与嵌套列表类似的方式显示它,但具有以下布局:
- 最后一个轴从左到右打印;
- 倒数第二个从上到下打印;
- 其余部分也从上到下打印,每个切片用空行分隔。
1.然后将一维数组打印为行,将二维数据打印为矩阵,将三维数据打印为矩数组表。
a = np.arange(5) # 一维数组
b = np.arange(12).reshape(3,4) #二维数组
c = np.arange(24).reshape(2,3,4) #三维数组
print(a)
print(b)
print(c)
2.如果数组太大而无法打印,NumPy会自动跳过数组的中心部分并仅打印角点:
print(np.arange(10000))
结果:
[ 0 1 2 … 9997 9998 9999 ]
print(np.arange(10000).reshape(100,100))
结果:
[[ 0 1 2 … 97 98 99]
[ 100 101 102 … 197 198 199]
[ 200 201 202 … 297 298 299]
…
[9700 9701 9702 … 9797 9798 9799]
[9800 9801 9802 … 9897 9898 9899]
[9900 9901 9902 … 9997 9998 9999]]
3.要禁用此行为并强制NumPy打印整个数组,可以使用更改打印选项set_printoptions
#Floating point precision can be set
import numpy as np
np.set_printoptions(precision=4)
print(np.array([1.123456789]))
结果:
[ 1.1235 ]
#Long arrays can be summarised
np.set_printoptions(threshold=10)
print(np.arange(100))
结果:
[ 0 1 2 … 97 98 99]
#Small results can be suppressed
#help(finfo)
# eps : float
# | The smallest representable positive number such that
# | ``1.0 + eps != 1.0``. Type of `eps` is an appropriate #floating
# | point type.
eps = np.finfo(float).eps
x = np.arange(4.)
x**2 - (x + eps)**2
结果:
array([ -4.9304e-32, -4.4409e-16, 0.0000e+00, 0.0000e+00])
np.set_printoptions(suppress=True)
x**2 - (x + eps)**2
结果:
array([-0., -0., 0., 0.])
#A custom formatter can be used to display array elements as desired:
np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)})
x = np.arange(3)
x
结果:
array([int: 0, int: -1, int: -2])
np.set_printoptions() # formatter gets reset
x
结果:
array([0, 1, 2])
#To put back the default options, you can use:
np.set_printoptions(edgeitems=3,infstr='inf',linewidth=75,nanstr='nan', precision=8,suppress=False, threshold=1000,formatter=None)
四.基本操作
数组上的算术运算符会应用到 元素 级别
- 元素 + - * (数乘) < > ==
a = np.array([2,3,4,5])
b = np.arange(4)
c = a + b
print(c)
d = a - b
print(d)
e = a**2
print(e)
f = 10*np.sin(a)
print(f)
print(a < 4) #bool类型
print(d == 2) #bool类型
- 矩阵乘 a @ b 或 a.dot(b)
A = np.array([[1,1],
[0,1]])
B = np.array([[2,0],
[3,4]])
print("A * B =",A * B) #元素之间对应相乘
print("A @ B =",A @ B) #矩阵相乘
print("A.dot(B) =",A.dot(B)) #矩阵相乘
- += *= 会直接更改被操作的矩阵数组而不会创建新的矩阵数组
a = np.ones((3,2),dtype = int)
b = np.random.random((3,2))
print("before change a = ",a)
a *= 3 # a *= 3后a被操作内容被改变而非重新创建
print("after *3 a = ",a)
b += a # b += a后b被操作,而a不变
print("after b += a a = ",a)
print("after b += a b = ",b)
a += b #报错,浮点型b不能自动转化为整型 !!!!!!!!!!!!!!
- 使用不同类型的数组进行操作,结果类型与更一般或更精准的数组相同(向上转换行为)
a = np.ones(3,dtype=np.int32)
b = np.linspace(0,pi,3)
print(b.dtype.name)
#float64
c = a + b
print(c)
print(c.dtype.name)
#float64
d = np.exp(c*1j)
print("c*1j = ",c*1j)
print(d)
print(d.dtype.name)
#complex128
- 一些一元操作 ndarry类方法实现
a = np.random.random((2,3)) #随机创建一个形状为(2,3)的数组
print(a)
print(a.sum()) #数组元素的总和
print(a.min()) #数组元素的最小值
print(a.max()) #数组元素的最大值
- 除此之外,还可以指定axis参数,沿数组的指定轴操作
b = np.arange(12).reshape(4,3)
print(b)
#[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
print(b.sum(axis = 0)) #按照"列"sum
#[18 22 26]
print(b.sum(axis = 1)) #按照"行"sum
# [ 3 12 21 30]
print(b.min(axis = 1)) #“行”求最小
# [0 3 6 9]
print(b.max(axis = 0)) #“列”求最大
# [ 9 10 11]
print(b.cumsum(axis = 0)) #按照"列"逐一迭代叠加
#[[ 0 1 2]
# [ 3 5 7]
# [ 9 12 15]
# [18 22 26]]
五.通函数 ufun
所谓通函数,就是python自带的函数。下给出一些简单的例子:
b = np.arange(3)
c = np.array([2,0,4])
d = np.random.random(3)
# 此三行为创建数组的三个方法
print("b = ",b)
print("c = ",c)
print("d = ",d)
print("np.exp(b) = ",np.exp(b)) # e**b
print("np.sqrt(b) = ",np.sqrt(b)) # b开平方根
print("np.add(b,c) = ",np.add(b,c)) # b,c相加
print("np.sort(c) = ",np.sort(c)) # 排序,默认从小到大
print("np.average(c) = ",np.average(c)) #求数组c的平均数
print("np.ceil(d) = ",np.ceil(d)) # 向上取整数
print(np.where(c > 2,c,-1)) # 若c>2则该元素不变,否则变成-1
print(np.where(c > 1)) # 返回值为满足条件的元素的索引所组成的数组
print(c[np.where(c > 1)]) # 返回值为数组中满足条件的元素
- np.where()
x = np.arange(9.).reshape(3, 3)
print(x)
print(np.where( x > 5 )) # 返回满足条件的数组(位置索引)
print(x[np.where( x > 3.0 )]) # result is 1D.
print(np.where(x < 5, x, -1)) # broadcasting.
print(np.where([[True, False], [True, True]],
[[1, 2], [3, 4]],
[[9, 8], [7, 6]]))
print(np.where([[True, False]],
[[1, 2]],
[[9, 8]]))
print(np.where([[0, 1], [1, 0]]))
print(np.where([1]))
- np.nonzero()
# np.nonzero(a)
#没有condition
x = np.array([[1,0,0], [0,2,0], [1,1,0]])
print(np.nonzero(x)) #返回值为两个数组,一个数组是不是0的x索引,另一个是y索引
print(x[np.nonzero(x)]) #返回值为一个数组,元素是x中不是0的所有元素
#有condition
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(np.nonzero(a > 3)) #返回值为数组,元素是满足a>3的bool型
print((a > 3).nonzero()) #两者等价
print(np.transpose(np.nonzero(x))) #返回一个数组 合并np.nonzero(x)产生的两个数组
小结:
- 更多通用函数,有需要的话可以查文档
- help() 函数查询函数,寻求帮助
- help(np.ndarray)