1、数组初始化
import numpy as np
# 列表传入生成数组
a = np.array([1, 2, 3, 4])
print(a)
# [1 2 3 4]
# 生成全0的数组,默认是浮点型
a = np.zeros(5)
print(a)
# [0. 0. 0. 0. 0.]
# 生成全1的数组,默认是浮点型
a = np.ones(5, dtype=np.int)
print(a)
# [1 1 1 1 1]
a = np.ones(5, dtype=np.bool)
print(a)
# [True True True True True]
# fill 将数组设为指定值
a = np.array([1, 2, 3, 4])
a.fill(5)
print(a)
# [5 5 5 5]
# 注意这里的fill的dtype和原始类型是一致的,否则会被强制转换
a.fill(2.5)
print(a)
# [2 2 2 2]
# 转换数据类型
a = np.array([1, 2, 3, 4])
a = a.astype(np.float) #需要将返回的数组重新赋值给a!!
a.fill(2.5)
print(a)
# [2.5 2.5 2.5 2.5]
# 生成整数序列
a = np.arange(1, 10)
print(a)
# [1 2 3 4 5 6 7 8 9]
a = np.arange(1, 10, 2) #1~10,不包括10,以2为间隔
print(a)
# [1 3 5 7 9]
# 生成等差数列
a = np.linspace(1, 10, 21) #1~10,包括10,一共21个元素
print(a)
# [ 1. 1.45 1.9 2.35 2.8 3.25 3.7 4.15 4.6 5.05 5.5 5.95
# 6.4 6.85 7.3 7.75 8.2 8.65 9.1 9.55 10. ]
# 生成普通0~1随机数
a = np.random.rand(5)
print(a)
# [0.71501666 0.8668771 0.80197722 0.85027734 0.07084488]
# 标准正态随机数
a = np.random.randn(5)
print(a)
# [ 1.93477333 -0.59122048 1.56949196 -0.20376461 -0.66881716]
# 随机整数
a = np.random.randint(1, 10, 6) #1~10(不包括10),生成6个随机整数
print(a)
# [7 6 6 8 9 3]
2、数组属性
import numpy as np
a = np.ones((3, 2))
print(a)
# [[1. 1.]
# [1. 1.]
# [1. 1.]]
# type,返回a的数据类型
print(type(a))
# <class 'numpy.ndarray'>
# dtype,返回a中元素的数据类型
print(a.dtype)
# float64
# shape,返回行和列数,结果为元组
print(a.shape)
# (3, 2)
print(np.shape(a))
# (3, 2)
# size,返回总元素个数
print(np.size(a))
# 6
# 返回数组的维度,向量1维,矩阵2维,通俗讲就是一开始‘[’的个数
print(a.ndim)
# 2
3、索引和切片
import numpy as np
a = np.array([0, 1, 2, 3])
# 索引第一个元素
print(a[0])
# 0
# 元素修改
a[0] = 10
print(a)
# [10 1 2 3]
# 切片
a = np.array([11, 12, 13, 14, 15])
print(a[1:3])
# [12 13]
# 负索引
print(a[1:-2])
# [12 13]
print(a[-4:3])
# [12 13]
# 省略参数
print(a[-2:])
# [14 15]
print(a[::2])
# [11 13 15]
# 切片应用举例,假设我们记录一部电影的累计票房
ob = np.array([21000, 21800, 22240, 23450, 25000])
# 可以这样计算每天的票房
# [21800, 22240, 23450, 25000] - [21000, 21800, 22240, 23450]
ob2 = ob[1:] - ob[:-1]
print(ob2)
# [ 800 440 1210 1550]
4、多维数组
import numpy as np
a = np.array([[0, 1, 2, 3],
[10, 11, 12, 13]])
print(a)
# [[ 0 1 2 3]
# [10 11 12 13]]
# 索引
print(a[1, 3]) #行,列
# 13
# 赋值
a[1, 3] = -1
print(a)
# [[ 0 1 2 3]
# [10 11 12 -1]]
# 返回一行
print(a[1])
# [10 11 12 -1]
# 返回一列
print(a[:, 1])
# [ 1 11]
import numpy as np
# 多维数组切片
a = np.array([[0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
print(a)
# [[ 0 1 2 3 4 5]
# [10 11 12 13 14 15]
# [20 21 22 23 24 25]
# [30 31 32 33 34 35]
# [40 41 42 43 44 45]
# [50 51 52 53 54 55]]
# 得到第一行的第4和第5两个元素
print(a[0, 3:5])
# [3 4]
# 得到最后两行的最后两列
print(a[-2:, -2:])
# [[44 45]
# [54 55]]
# 得到第三列
print(a[:, 2])
# [ 2 12 22 32 42 52]
# 得到第3第5行的奇数列
print(a[2:5:2, ::2])
# [[20 22 24]
# [40 42 44]]
5、引用机制
不同于List的使用,numpy中切片使用的是引用机制。
import numpy as np
a = np.array([1, 2, 3, 4])
b = a[2:4]
b[0] = 10
print(a)
# out:
# [ 1 2 10 4]
引用机制意味着,Python并没有为b分配新的空间来存储它的值,而是让b指向了a所分配的内存空间,因此,改变b会改变a的值。而这种现象在列表中并不会出现:
a = [1, 2, 3, 4]
b = a[2:4]
b[0] = 10
print(a)
# out:
# [1, 2, 3, 4]
这样做的好处在于,对于很大的数组,不用大量复制多余的值,节约了空间。
缺点在于,可能出现改变一个值改变另一个值的情况。
一个解决方法是使用copy()
方法产生一个复制,这个复制会申请新的内存:
import numpy as np
a = np.array([1, 2, 3, 4])
b = a[2:4].copy()
b[0] = 10
print(a)
# out:
# [1 2 3 4]
6、花式索引
花式索引不同于切片操作,不再使用引用机制,而是返回原对象的一个复制。
一维花式索引:
import numpy as np
a = np.arange(0, 100, 10)
print(a)
# [ 0 10 20 30 40 50 60 70 80 90]
# 通过列表:
index = [1, 2, -3]
y = a[index]
print(y)
# [10 20 70]
y[0] = 1
print(y)
# [ 1 20 70]
print(a) #不会改变a!
# [ 0 10 20 30 40 50 60 70 80 90]
# 通过bool数组,维度必须和a一致
mask = np.array([0, 2, 2, 0, 0, 1, 0, 0, 1, 0], dtype=np.bool)
print(mask)
# [False True True False False True False False True False]
print(a[mask])
# [10 20 50 80]
二维花式索引:
import numpy as np
a = np.array([[0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
print(a)
# [[ 0 1 2 3 4 5]
# [10 11 12 13 14 15]
# [20 21 22 23 24 25]
# [30 31 32 33 34 35]
# [40 41 42 43 44 45]
# [50 51 52 53 54 55]]
# 返回一条次对角线上的5个值
print(a[[0, 1, 2, 3, 4], [1, 2, 3, 4, 5]])
# [ 1 12 23 34 45]
# 返回最后三行的第1,3,5列,和切片a[3:, ::2]很像,注意对比!
print(a[3:, [0, 2, 4]])
# [[30 32 34]
# [40 42 44]
# [50 52 54]]
# 也可以用mask的方式
mask = np.array([1, 0, 1, 0, 0, 1], dtype=np.bool)
print(a[mask, 2])
# [ 2 22 52]
7、where语句
where(array)
where
会返回所有非零元素的索引。
import numpy as np
a = np.array([0, 12, 5, 20])
# 判断数组中的元素是不是大于10:
print(a > 10)
# [False True False True]
# 数组中所有大于10元素的索引位置
print(np.where(a > 10))
# (array([1, 3], dtype=int64),)
# 获得数组中大于10的元素,其实就是花式索引
print(a[a > 10])
# [12 20]
print(a[np.where(a > 10)])
# [12 20]
8、类型转换
# 这里其实会自动转换成float
a = np.array([1.5, -3], dtype=np.float)
print(a)
# asarray 函数
a = np.array([1, 2, 3])
b = np.asarray(a)
print(id(a), id(b))
# 1662560396512 1662560396512 a、b类型相同时,b和a同一个引用
b = np.array(a)
print(id(a), id(b))
# 1662560396512 1664299540528 array方法不同,会返回新数组
b = np.asarray(a, dtype=np.float)
print(id(a), id(b))
# 1662560396512 1664299552240 转换了类型后,不再是同一个引用
print(b)
# [1. 2. 3.]
# astype 方法,返回新的数组
a = np.array([1, 2, 3], dtype=np.int)
b = a.astype(np.int)
print(id(a), id(b))
# 2055030138000 2054646487440 即使a、b类型相同,也不是同一个引用
a = a.astype(np.float)
print(a)
# [1. 2. 3.]
9、数组操作
数组排序,最值,求和等功能。
import numpy as np
# 电影名称
mv_name = ['肖申克的救赎', '控方证人', '美丽人生', '阿甘正传', '霸王别姬'
'泰坦尼克号', '希特勒的名单', '这个杀手不太冷', '盗梦空间', '千与千寻']
# 评分人数
mv_num = np.array([692795, 42995, 327855, 580897, 478523,
157074, 306904, 662552, 284652, 159302])
# 评分
mv_score = np.array([9.6, 9.5, 9.5, 9.4, 9.4, 9.4, 9.4, 9.3, 9.3, 9.3])
# 电影时长
mv_length = np.array([142, 116, 116, 142, 171, 194, 195, 133, 109, 92])
# 数组排序
print(np.sort(mv_num)) #不会改变 mv_num 数组本身
# [ 42995 157074 159302 284652 306904 327855 478523 580897 662552 692795]
# argsort 函数 返回从小到大的排列在数组中的索引位置
print(np.argsort(mv_num))
# [1 5 9 8 6 2 4 3 7 0]
# argsort应用:获取评论人数最少的电影
print(mv_name[np.argsort(mv_num)[0]])
# 控方证人
# 求和,两种方式
print(np.sum(mv_num))
# 3693549
print(mv_num.sum())
# 3693549
# 最大值,两种方式
print(np.max(mv_length))
# 195
print(mv_length.max())
# 195
# 最小值,两种方式
print(np.min(mv_length))
# 92
print(mv_length.min())
# 92
# 均值,两种方式
print(np.mean(mv_length))
# 141.0
print(mv_length.mean())
# 141.0
# 标准差,两种方式
print(np.std(mv_length))
# 33.713498780162226
print(mv_length.std())
# 33.713498780162226
# 相似的还有abs,exp,median(中值),cumsum(累积和),sin,cos等等
# 相关系数矩阵
print(np.cov(mv_score, mv_length))
# [[9.88888889e-03 4.55555556e-01]
# [4.55555556e-01 1.26288889e+03]]
多维数组操作(重新定义形状、转置):
import numpy as np
a = np.arange(6)
print(a)
# [0 1 2 3 4 5]
# 数组修改1,这种方法会直接改变原本数组的值
a.shape = 2, 3
print(a)
# [[0 1 2]
# [3 4 5]]
print(a.shape)
# (2, 3)
# reshape 方法,返回一个新的数组
a = np.arange(6)
print(a)
# [0 1 2 3 4 5]
b = a.reshape(2, 3)
print(b)
# [[0 1 2]
# [3 4 5]]
print(a)
# [0 1 2 3 4 5]
# 转置,两种方法均不会改变原始数组
print(b.T)
# [[0 3]
# [1 4]
# [2 5]]
print(b.transpose())
# [[0 3]
# [1 4]
# [2 5]]
print(b)
# [[0 1 2]
# [3 4 5]]
10、数组连接

有时我们需要将不同的数组按照一定的顺序连接起来:
concatenate((a0, a1.…, aN), axis=0)
注意,这些数组要用()
包括到一个元组中去。
除了给定的轴外,这些数组其他轴的长度必须一致。
默认沿着第一维进行连接:
# 数组连接
x = np.array([[0, 1, 2], [10, 11, 12]])
y = np.array([[50, 51, 52], [60, 61, 62]])
# 默认沿着第一维进行连接,axis=0
z = np.concatenate((x, y))
print(z)
# [[ 0 1 2]
# [10 11 12]
# [50 51 52]
# [60 61 62]]
沿着第二维进行连接:
# 沿着第二维拼接
z = np.concatenate((x, y), axis=1)
print(z)
# [[ 0 1 2 50 51 52]
# [10 11 12 60 61 62]]
注意到这里x和y的形状是一样的,还可以将它们连接成三维的数组,但是concatenate不能提供这样的功能,不过可以通过以下方法实现:
# 三维数组
z = np.array((x, y))
print(z)
# [[[ 0 1 2]
# [10 11 12]]
#
# [[50 51 52]
# [60 61 62]]]
事实上,Numpy提供了分别对应这三种情况的函数:
vstack
hstack
dstack
z = np.vstack((x, y))
print(z)
# [[ 0 1 2]
# [10 11 12]
# [50 51 52]
# [60 61 62]]
z = np.hstack((x, y))
print(z)
# [[ 0 1 2 50 51 52]
# [10 11 12 60 61 62]]
# 注意这里和上面的array结果不一样
z = np.dstack((x, y))
print(z)
# [[[ 0 50]
# [ 1 51]
# [ 2 52]]
#
# [[10 60]
# [11 61]
# [12 62]]]
网友评论