1 数据维度
1.1 创建数据
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
| import numpy as np
arr1 = np.array([2, 4, 6, 8]) print("arr1数据:\n", arr1, "\narr1维度:", arr1.ndim)
arr2 = np.array([[2, 4, 6, 8], [6, 8, 10, 12], [8, 10, 12, 14]]) print("arr2数据:\n", arr2, "\narr2维度:", arr2.ndim)
arr3 = np.array([ [ [2, 4, 6, 8], [6, 8, 10, 12], [8, 10, 12, 14] ], [ [21, 41, 6, 8], [61, 81, 10, 12], [81, 101, 12, 14] ],
]) print("arr3数据:\n", arr3, "\narr3维度:", arr3.ndim)
|
运行结果如下:
array.ndim
可以得到Numpy Array
对象的维度。
1.2 添加数据
1.2.1 一维数据
一维数据直接使用np.concatenate
。
1 2 3 4 5 6 7 8
| import numpy as np
arr1 = np.array([2, 4, 6, 8]) arr2 = np.array([10, 12]) arr = np.concatenate([arr1, arr2]) print("arr1数据:", arr1, "\narr1维度:", arr1.ndim) print("arr2数据:", arr2, "\narr2维度:", arr2.ndim) print("arr数据:", arr, "\narr维度:", arr.ndim)
|
输出结果:
1.2.2 二维数据
首先需要添加一个维度,然后在第一个维度上添加数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import numpy as np
arr1 = np.array([2, 4, 6, 8]) arr2 = np.array([10, 12, 14, 16])
arr1 = np.expand_dims(arr1, 0) arr2 = arr2[np.newaxis, :]
print("arr1加维度后:", arr1) print("arr2加维度后:", arr2)
arr = np.concatenate([arr1, arr2]) print("扩展后:\n", arr)
|
输出结果:
1.3 合并数据
上述是在第一个维度上叠加,也可以在第二个维度上叠加,只需要给np.concatenate
输入一个参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import numpy as np arr1 = np.array([2, 4, 6, 8]) arr2 = np.array([10, 12, 14, 16])
arr1 = np.expand_dims(arr1, 0) arr2 = arr2[np.newaxis, :]
print("arr1加维度后:", arr1) print("arr2加维度后:", arr2)
arr = np.concatenate([arr1, arr2], axis=0) print("第一维度叠加:\n", arr)
arr = np.concatenate([arr1, arr2], axis=1) print("第二维度叠加:\n", arr)
|
输出结果:
只要维度可以对齐,可以在任意维度上进行合并操作,但是有些数据维度对不齐,就无法合并,例如:
1 2 3 4 5 6 7 8 9 10
| import numpy as np
arr1 = np.array([[2, 4, 6, 8], [1, 2, 3, 4]]) arr2 = np.array([[10, 12, 14], [3, 2, 1]])
arr = np.concatenate([arr1, arr2], axis=1) print("第二维度叠加:\n", arr)
|
对于二维数据,可以使用np.vstack()
和np.hstack()
进行竖直和水平合并:
1 2 3 4 5 6 7 8 9 10
| import numpy as np
arr1 = np.array([[2, 4, 6, 8], [1, 2, 3, 4]]) arr2 = np.array([[10, 12, 14, 16], [3, 2, 1, 0]])
arr = np.vstack([arr1, arr2]) print("竖直合并:\n", arr)
arr = np.hstack([arr1, arr2]) print("水平合并:\n", arr)
|
输出结果:
1.4 观察形态
可以使用array.size
获取元素总个数,使用np.shape
获取行数和列数:
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
| import numpy as np
arr = np.array([[2, 4, 6, 8], [1, 2, 3, 4]])
print("元素总数:", arr.size)
print("第一个维度(行):", arr.shape[0]) print("第二个维度(列):", arr.shape[1]) print("所有维度:", arr.shape)
arr1 = np.array([ [ [1, 2, 1], [2, 3, 1], [1, 2, 1], [1, 2, 1] ], [ [3, 4, 1], [1, 2, 1], [1, 2, 1], [4, 5, 1] ] ])
print("元素总数:", arr1.size)
print("第一个维度:", arr1.shape[0]) print("第二个维度:", arr1.shape[1]) print("第三个维度:", arr1.shape[2]) print("所有维度:", arr1.shape)
|
输出结果:
2 数据选择
2.1 单个选取
可以直接用索引取值,也可以一次取多个:
1 2 3 4 5 6
| import numpy as np
a = np.array([1, 2, 3]) print("a[0]:", a[0]) print("a[1]:", a[1]) print("a[0,1]:", a[[0, 1]])
|
输出结果:
二维数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import numpy as np
b = np.array([ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ])
print("b[1]:\n", b[1])
print("b[1,0]:\n", b[1, 0])
print("b[[1,0],[2,3]]:\n", b[[1, 0], [2, 3]])
|
输出结果:
2.2 切片划分
一般形式为array[a:b,c:d]
,a:b
表示从第一个维度从a到b-1,以此类推,:
前缺省值为最小,:
后缺省值为最大,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import numpy as np
b = np.array([ [ [1, 2, 3, 4], [5, 6, 7, 8], ], [ [9, 10, 11, 12], [13, 14, 15, 16] ], [ [17, 18, 19, 20], [21, 22, 23, 24] ] ])
print("***********b[:2]************:\n", b[:2]) print("*********b[:2, 1:2]*********:\n", b[:2, 1:2]) print("*****b[1:3, 1:2, -3:-2]*****:\n", b[1:3, 1:2, -3:-2])
|
输出结果为:
2.3 条件筛选
上述选择方式是按照位置进行选择,下面介绍按照条件进行选择数据的方式。
1 2 3 4 5 6 7 8 9
| import numpy as np
a = np.array([ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ])
print(a[a > 7])
|
输出结果:
上面选取的a
中大于7的数据,下面演示了a[a>7]
中发生了什么。
1 2 3 4 5 6 7 8 9 10 11 12
| import numpy as np
a = np.array([ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ])
condition = a > 7 print("condition:\n", condition)
print("a[condition]:\n", a[condition])
|
从图中可以看出,condition是一种True/False,则只要我们得到一个True/False数据,我们就可以筛选,这就是它筛选的底层逻辑。
除了这种直接使用[]
的形式,Numpy还有一个专用的函数来做数据筛选,还可以将满足条件的位置变成设定的数字。
下面展示了将上述a
中大于7的数据变成1,否则就是0:
3 基础运算
3.1 加减乘除
Numpy Array对象可以直接使用+-*/
进行运算,如:
1 2 3 4 5 6 7 8
| import numpy as np
a = np.array([1, 2, 3, 4])
print("a + 3:", a + 3) print("a - 3:", a - 3) print("a * 3:", a * 3) print("a / 3:", a / 3)
|
输出结果:
矩阵的点积运算:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import numpy as np
a = np.array([ [1, 2], [3, 4] ]) b = np.array([ [5, 6], [7, 8] ])
print(a.dot(b)) print(np.dot(a, b))
|
两种方法结果一样:
还有矩阵外积np.outer()
、矩阵内积np.inner()
(和np.dot()
略有不同,可以理解为np.dot(a,b) = np.inner(a,b.transpose())
)。
3.2 数据统计分析
可以通过以下方法获得最值、累加、累乘、平均数等统计参数,注意有些方法具有两种写法,比如np.max(a)
和a.max()
;有的只有一种写法,比如np.median(a)
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import numpy as np
a = np.array([0, 1, 32, 56, 20, 0, 13, 1])
print("最大:", np.max(a), a.max()) print("最小:", np.min(a), a.min()) print("累加:", np.sum(a), a.sum()) print("累乘:", np.prod(a), a.prod()) print("总数:", np.size(a), a.size) print("平均数:", np.mean(a), a.mean()) print("标准差:", np.std(a), a.std())
print("中位数:", np.median(a)) print("非零总数:", np.count_nonzero(a))
|
3.3 特殊运算符号
3.3.1 定位最值
有时候我们不关心最大值和最小值是多少,我们关心的是其对应的序号,此时可以使用np.argmax()
和np.argmin()
,比如:
1 2 3 4 5 6 7 8
| import numpy as np
a = np.array([150, 166, 183, 170]) name = ["小明", "小红", "小刚", "小亮"] high_idx = np.argmax(a) low_idx = np.argmin(a) print("{} 最高".format(name[high_idx])) print("{} 最矮".format(name[low_idx]))
|
输出结果:
3.3.2 取整
1 2 3 4 5
| import numpy as np
a = np.array([150.1, 166.4, 183.7, 170.8]) print("向上取整:", np.ceil(a)) print("向下取整:", np.floor(a))
|
输出结果:
3.3.3 取值截取
给定一组数据和上下限,需要将小于下限的值赋值下限,大于上限的值赋值上限,如下:
1 2 3 4
| import numpy as np
a = np.array([150.1, 166.4, 183.7, 170.8]) print("clip:", a.clip(160, 180))
|
输出结果:
4 改变数据姿态
4.1 添加维度
可以使用np.newaxis
,其实它和None
一样,比如:
1 2 3 4 5 6 7 8 9 10
| import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
a_2d = a[np.newaxis, :] print("np.newaxis: ", np.newaxis) print("a_2d: ", a_2d, a_2d.shape)
a_none = a[:, None] print("a_none: ", a_none, a_none.shape)
|
输出结果:
可以看出np.newaxis
其值就是None
,需要注意添加维度的位置。
利用np.expand_dims()
函数:
1 2 3 4 5 6 7 8
| import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
a_expand = np.expand_dims(a, axis=0) print("a_expand.shape: ", a_expand, a_expand.shape) a_expand = np.expand_dims(a, axis=1) print("a_expand.shape: ", a_expand, a_expand.shape)
|
输出结果:
除了添加维度,还可以减少维度,当然只能减少shape为1的那些维度,因为这样减掉该维度后不丢失数据:
1 2 3 4 5 6 7 8 9 10 11
| import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
a_expand = np.expand_dims(a, axis=1) print("a_expand.shape: ", a_expand, a_expand.shape)
a_squeeze = np.squeeze(a_expand) a_squeeze_axis = a_expand.squeeze(axis=1) print(a_squeeze, a_squeeze.shape) print(a_squeeze_axis, a_squeeze_axis.shape)
|
输出结果:
可以使用np.reshape()
改变数据结构,让数据重新“站队”:
1 2 3 4 5 6 7 8 9
| import numpy as np
a = np.array([1, 2, 3, 4, 5, 6]) a1 = a.reshape([2, 3]) a2 = a.reshape([3, 1, 2]) print("a1 shape:", a1.shape) print(a1) print("a2 shape:", a2.shape) print(a2)
|
输出结果:
4.2 合并
np.column_stack()
和np.row_stack()
合并:
1 2 3 4 5 6 7 8 9 10 11
| import numpy as np
feature_a = np.array([1, 2, 3, 4, 5, 6]) feature_b = np.array([11, 22, 33, 44, 55, 66]) c_stack = np.column_stack([feature_a, feature_b]) print(c_stack)
sample_a = np.array([0, 1.1, 12, 1, 2.3, 1]) sample_b = np.array([1, 2.2, 12, 12, 123, 1]) c_stack = np.row_stack([sample_a, sample_b]) print(c_stack)
|
看似与np.vstack
和np.hstack()
类似,但是它们存在一些区别,比如:
1 2 3 4 5 6 7 8 9 10 11
| import numpy as np
feature_a = np.array([1, 2, 3, 4, 5, 6])[:, None] feature_b = np.array([11, 22, 33, 44, 55, 66])[:, None] c_stack = np.hstack([feature_a, feature_b]) print(c_stack)
sample_a = np.array([0, 1.1])[None, :] sample_b = np.array([1, 2.2])[None, :] c_stack = np.vstack([sample_a, sample_b]) print(c_stack)
|
使用np.vstack
和np.hstack()
必须先保证维度信息是正确的,而np.column_stack()
和np.row_stack()
会自动处理维度信息。
使用np.concatenate()
可以在任意维度合并:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import numpy as np
a = np.array([ [1, 2], [3, 4] ]) b = np.array([ [5, 6], [7, 8] ])
print(np.concatenate([a, b], axis=0)) print(np.concatenate([a, b], axis=1))
|
4.3 拆解
np.vsplit()
和np.hsplit()
实现横着、竖着拆解。
如果直接在 indices_or_sections
后填入数字,就是要整分的段数, 而如果接着的是一个列表,那就按照列表中的 index 来取区间。
1 2 3 4 5 6 7 8 9 10
| import numpy as np
a = np.array( [[1, 11, 2, 22], [3, 33, 4, 44], [5, 55, 6, 66], [7, 77, 8, 88]] ) print(np.vsplit(a, indices_or_sections=2)) print(np.vsplit(a, indices_or_sections=[2, 3]))
|
输出结果:
np.split()
在任一维度拆解:
1 2 3 4 5 6 7 8 9 10
| import numpy as np
a = np.array( [[1, 11, 2, 22], [3, 33, 4, 44], [5, 55, 6, 66], [7, 77, 8, 88]] ) print(np.split(a, indices_or_sections=2, axis=0)) print(np.split(a, indices_or_sections=[2, 3], axis=1))
|
输出结果:
5 设置输出格式
1
| np.set_printoptions(precision=None, threshold=None, linewidth=None, suppress=None, formatter=None)
|
precision:控制输出结果的精度(即小数点后的位数),默认值为8
threshold:当数组元素总数过大时,设置显示的数字位数,其余用省略号代替(当数组元素总数大于设置值,控制输出值得个数为6个,当数组元素小于或者等于设置值得时候,全部显示),当设置值为sys.maxsize(需要导入sys库),则会输出所有元素
linewidth:每行字符的数目,其余的数值会换到下一行
suppress:小数是否需要以科学计数法的形式输出
formatter:自定义输出规则
6 矩阵相关
6.1 矩阵求逆
np.linalg.inv(A)
如果是矩阵对象(np.matrix
),可以直接通过.I
求逆。
1 2 3 4 5 6 7 8
| import numpy as np
a = np.array([[1, 2], [3, 4]]) print(np.linalg.inv(a))
A = np.matrix(a) print(A.I)
|
6.2 矩阵求特征值及特征向量
np.linalg.eig(A)
1 2 3 4 5 6
| mat = np.array([[0, 1, 0, 1, 1], [1, 0, 1, 0, 0], [0, 1, 0, 0, 1], [1, 0, 0, 0, 1], [1, 0, 1, 1, 0]]) eigen_value, feature_vector = np.linalg.eig(mat)
|
参考资料:Numpy 数据怪兽 | 莫烦Python (mofanpy.com).