Numpy学习笔记
之前没有花时间去专门学Numpy,都是用到什么就草草查一下,最近在学DeepLearning,就决定还是系统地把Numpy学一遍。
一.Numpy基础篇
https://www.runoob.com/numpy/numpy-tutorial.html
大部分跟着菜鸟教程这个网站学的,上面有的基础知识点就不赘述了,只写一些值得特别注意的or没见过用法or自己的理解。
1.dtype(数据类型对象)
dt = np.dtype(np.int32) #或np.dtype("i4")
print(dt)
#输出结果:int32
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print(student)
#输出结果:
#[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')]
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a)
#输出结果:
#[('abc', 21, 50.0), ('xyz', 18, 75.0)]
这个用法很像C语言里的结构体,先用np.dtype定义一个结构体里面的属性,然后用np.array实例化出很多对象,存在一个numpy数组里。
简单来说:创建了一个numpy-array数组,其中每个元素类型为之前定义好的dtype='student'。
2.ndarray.itemsize
ndarray.itemsize 以字节的形式返回数组中每一个元素的大小。
# 数组的 dtype 为 int8(一个字节)
x = np.array([1,2,3,4,5], dtype = np.int8)
print (x.itemsize) #1
# 数组的 dtype 现在为 float64(八个字节)
y = np.array([1,2,3,4,5], dtype = np.float64)
print (y.itemsize) #8
3.numpy.arange
numpy.arange(start=0, stop, step=1, dtype)
(1)default:start=0,可以只传一参数这样用(结果为从0开始的n个数字):
x = np.arange(5)
print (x) #[0 1 2 3 4]
(2)stop不包含:再借用数学”黑话“,[start, stop) 是一个左闭右开区间。
(3)dtype:如果没有显示指定,则会使用输入数据的类型
4.numpy.linspace
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
默认包含stop
参数 | 描述 |
---|---|
stop | 序列的终止值,如果endpoint为true,该值包含于数列中 |
num | 要生成的等步长的样本数量,默认为50 |
endpoint | 该值为 ture 时,数列中中包含stop值,反之不包含,默认是True |
retstep | 如果为 True 时,生成的数组中会显示间距,反之不显示 |
a = np.linspace(1,10,10,retstep='true')
print(a)
#(array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]), 1.0)
5.numpy.logspace
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
start:始于base的start次方
stop:终于base的stop次方
a = np.logspace(1,3,num=10)
print(a)
#array([ 10. , 16.68100537, 27.82559402, 46.41588834,
# 77.42636827, 129.1549665 , 215.443469 , 359.38136638,
# 599.48425032, 1000. ])
a = np.logspace(0,8,9,base=2)
print(a)
#array([ 1., 2., 4., 8., 16., 32., 64., 128., 256.])
6.Numpy索引共享空间
a = np.arange(1,5)
print(a) #[1 2 3 4]
b = a[1:3]
print(b) #[2 3]
a[1]=999
print(b) #[999 3]
7.Numpy高级索引
7.1整数数组索引
获取数组中(0,0),(1,1)和(2,0)位置处的元素
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]]
print (y) #[1 4 5]
numpy数组也可做索引
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
#array([[ 0, 2],
# [ 9, 11]])
7.2布尔索引
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print (x)
#[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
print (x[x > 5])
#[ 6 7 8 9 10 11]
7.3花式索引
花式索引不共享空间!而是将数据复制到新数组中
(1)传入索引数组
a = np.arange(32).reshape([8,4])
print(a)
#[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]
# [24 25 26 27]
# [28 29 30 31]]
b = a[ [4,2,1,7] ]
print(b)
# [[16 17 18 19]
# [ 8 9 10 11]
# [ 4 5 6 7]
# [28 29 30 31]]
(2)传入多个索引数组(用np.ix_)
a[np.ix_([1,3],[2,5])]
返回数组 :
[[a[1,2] a[1,5]], [a[3,2] a[3,5]]]
np.ix_:
得到两个数组的笛卡尔积
内部实际工作机制:
a = np.ix_([1,2,3],[4,5,6])
print(a)
# (array([[1],
# [2],
# [3]]), array([[4, 5, 6]]))
如果没有用np.ix_就变成了7.1 (1)中的数组索引,只返回a[1,4],a[2.5],a[3,6]组成的数组。
8.numpy.nditer
迭代对象numpy.nditer可以逐个访问数组元素
a = np.arange(6).reshape(2,3)
print(a) # array([[0, 1, 2],
# [3, 4, 5]])
for x in np.nditer(a):
print(x,end=",") # 0,1,2,3,4,5,
for x in np.nditer(a,order='F'):
print(x,end=",")
# 0,3,1,4,2,5,
迭代访问的顺序并不是C-order(行优先),而是和数组内存布局一致,这样做是为了提升访问的效率。
b = np.asarray(a,order='F')
print(b)
# array([[0, 1, 2],
# [3, 4, 5]])
for x in np.nditer(b):
print(x,end=",")
# 0,3,1,4,2,5,
关于转置在内存中的顺序:
c = a.T
print(c)
#[[0 3]
# [1 4]
# [2 5]]
for x in np.nditer(c):
print(x,end=",")
# 0,1,2,3,4,5,
d = a.T.copy()
print(d)
#[[0 3]
# [1 4]
# [2 5]]
for x in np.nditer(d):
print(x,end=",")
# 0,3,1,4,2,5,
另外c = a.T与a共享内存,而d = a.T.copy()真正的复制了一个矩阵。改变a的值,c会随之改变(反之,改c时a也会被改),而d不会改变。
若在遍历过程中想修改元素值:
for x in np.nditer(a, op_flags=['readwrite']):
#或
for x in np.nditer(a, op_flags=['write-only']):
#默认值 op_flags=read-only
二.函数艳遇篇
人们说,艳遇总是美好而短暂的,记录学习之旅中与各位函数的邂逅,想在脑海里留下些你们面容的残枝掠影~
行了,演不下去了,就是记点遇到的函数。
1.np.loadtxt()
作用:从.txt文件中读取数据存为数组。
M = np.loadtxt("test.txt")
#test.txt内容为:
#1 2 3
#4 5 6
print(M)
#[[1. 2. 3.]
# [4. 5. 6.]]
loadtxt自动处理换行符
M = np.loadtxt("test2.txt",delimiter=',')
#test2.txt内容为:
#1,2,3
#4,5,6
print(M)
#[[1. 2. 3.]
# [4. 5. 6.]]
delimiter指定.txt文件中元素的间隔符,默认为空格。当间隔符不是空格时必须显示指定。
2.numpy.nonzero
返回非零索引值
x = np.array([1,2,0,0,3,0,5])
np.nonzero(x)
#(array([0, 1, 4, 6]),)
3.numpy.tile
就是把数组”平铺“得到新数组,这里讲的很明白:
https://blog.csdn.net/qq_18433441/article/details/54897250
三.实战技巧篇
1.乾坤大挪移(逆序数组...)
a = np.arange(5)
b = a[::-1]
print(a) #[0 1 2 3 4]
print(b) #[4 3 2 1 0]
a = np.arange(6).reshape(2,3)
b = a[::-1]
c = a[:,::-1]
d = a[::-1,::-1]
print(a)
print(b)
print(c)
print(d)
# [[0 1 2]
# [3 4 5]]
# [[3 4 5]
# [0 1 2]]
# [[2 1 0]
# [5 4 3]]
# [[5 4 3]
# [2 1 0]]
2.计算索引:numpy.unravel_index(indices, dims, order='C')
求第n个元素在数组中的(多维结构)索引。
也就是,已知平铺后的一维索引,求原多维结构的索引。
#求在7×8×9的多维数组中,第100个元素的索引
print(np.unravel_index(100,[7,8,9]))
#(1, 3, 1)
例如,常常这样用:
a = np.random.random([3,4])
a_max = a.argmax()
print(a)
print(a_max)
print(np.unravel_index(a_max,a.shape))
# [[0.32974103 0.62543059 0.5068712 0.20391591]
# [0.24423194 0.24260907 0.40326733 0.31111273]
# [0.28750882 0.67934444 0.5857911 0.67283181]]
# 9
# (2, 1)