NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

  • 机器学习模型:在编写机器学习算法时,需要对矩阵进行各种数值计算。例如矩阵乘法、换位、加法等。NumPy提供了一个非常好的库,用于简单(在编写代码方面)和快速(在速度方面)计算。NumPy数组用于存储训练数据和机器学习模型的参数。
  • 图像处理和计算机图形学:计算机中的图像表示为多维数字数组。NumPy成为同样情况下最自然的选择。实际上,NumPy提供了一些优秀的库函数来快速处理图像。例如,镜像图像、按特定角度旋转图像等。
  • 数学任务:NumPy对于执行各种数学任务非常有用,如数值积分、微分、内插、外推等。因此,当涉及到数学任务时,它形成了一种基于Python的MATLAB的快速替代

Ndarray 对象

NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。

ndarray 对象是用于存放同类型元素的多维数组。

ndarray 中的每个元素在内存中都有相同存储大小的区域。

ndarray 内部由以下内容组成:

  • 一个指向数据(内存或内存映射文件中的一块数据)的指针。
  • 数据类型或 dtype,描述在数组中的固定大小值的格子。
  • 一个表示数组形状(shape)的元组,表示各维度大小的元组。
  • 一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。

跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1] 或 obj[:,::-1] 就是如此。

创建array:

numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

名称 描述
object 数组或嵌套的数列
dtype 数组元素的数据类型,可选
copy 对象是否需要复制,可选
order 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok 默认返回一个与基类类型一致的数组
ndmin 指定生成数组的最小维度

创建数组

import numpy as np

a = np.array([0,1,2,3,4]);
b = np.array((0,1,2,3,4));
c = np.arange(5);#array range:数组范围
d = np.linspace(0,2*np.pi,5);#区间等分 这行代码表示,生成 0--2倍π 的5等分数组

print(a);
print(b);
print(c);
print(d);
print(a[3]);
print(np.pi);#π值
>>>
[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]
[0. 1.57079633 3.14159265 4.71238898 6.28318531]
3
3.141592653589793

shape 返回array对象结构

import numpy as np

a = [['a',1],[3,4],[5,6]];#列表
b = np.array(a);#创建数组对象
s = b.shape;
print(b)
print(s)
>>>
[['a' '1']
['3' '4']
['5' '6']]
(3, 2)

#在列表元素不规则时
a = [['a',1],[3],[5,6]];#列表
b = np.array(a, ndmin = 2);#创建数组对象
s = b.shape;
print(b)
print(s)
>>>
[[list(['a', 1]) list([3]) list([5, 6])]]
(1, 3)

zeros 生成设置长度,元素为0的数组

import numpy as np

a = np.zeros((5))
b = np.zeros(5)
c = np.zeros((5,5))
d = np.ones((5,5))
#生成随机数组
e = np.random.random(5) #创建一维随机数数组(0-1)
f = np.random.rand(3,3) #创建多维随机数数组(0-1)
g = np.random.uniform(0,10) #生成制定范围随机数(小数)
h = np.random.randint(0,10) #生成制定范围随机数(整数)
i = np.random.normal(1, 0.5, (2, 3))
#定均值/标准差/维度的正态分布

print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
print(g)
print(h)
print(i)
>>>
[0. 0. 0. 0. 0.]

[0. 0. 0. 0. 0.]

[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]

[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]

[0.07584956 0.53922277 0.65595745 0.50618522 0.65382513]

[[0.88587577 0.09837355 0.36501315]
[0.86418709 0.7405183 0.27676235]
[0.50512548 0.33444731 0.35448713]]

3.458820958322868

5

[[0.88792527 0.62901564 1.32830452]
[1.26957326 2.35533203 0.95984656]]

数组四则运算

import numpy as np

a = np.array([[1,2],[3,4]]);
b = np.array([[5,6],[7,8]]);

sum = a + b;
difference = a - b;
product = a * b; #这里的*号应该叫哈达马乘积
quotient = a / b;
matrix = a.dot(b);#矩阵乘法运算

c = np.array([[80, 88], [82, 81], [84, 75], [86, 83], [75, 81]])
d = a > 80; #比较运算
e = np.where(c < 80, 0, 90); #三元运算

print(sum)
print(difference)
print(product)
print(quotient)
print(matrix)
print(c)
print(d)
print(e)
>>>
[[ 6 8] [10 12]]
[[-4 -4] [-4 -4]]
[[ 5 12] [21 32]]
[[0.2 0.33333333] [0.42857143 0.5]]
[[19 22] [43 50]]
#矩阵乘积推导
# 1 2 * 5 6 = 1*5+2*7 1*6+2*8 = 19 22
# 3 4 7 8 3*5+4*7 3*6+4*8 43 50

[[80 88]
[82 81]
[84 75]
[86 83]
[75 81]]

[[False True]
[ True True]
[ True False]
[ True True]
[False True]]

[[90 90]
[90 90]
[90 0]
[90 90]
[ 0 90]]

数组切片

import numpy as np

a = 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,25]]);

b = np.random.random(10);
c = b.reshape([2,5]); #数组转换格式

print(a[2,4])
print(a[0,1:4])
print(a[1:4,0])
print(a[::2,::2])
print(a[:,1])
print(a[...,1]) #第一列
print(a[1,...]) #第一行
print(a[1:,...]) #第一行后所有
#':'符号说明,起始(默认:0):终点(默认:最大值):跨度
print(b)
print(c)
>>>
15
[2 3 4]
[ 6 11 16]
[[ 1 3 5]
[11 13 15]
[21 23 25]]
[ 2 7 12 17 22]
[ 2 7 12 17 22]
[ 6 7 8 9 10]
[[ 6 7 8 9 10]
[11 12 13 14 15]
[16 17 18 19 20]
[21 22 23 24 25]]

[0.64739463 0.68015483 0.55690572 0.23061854 0.18691435 0.56046423 0.33049387 0.5747057 0.66658586 0.34418833]

[[0.64739463 0.68015483 0.55690572 0.23061854 0.18691435]
[0.56046423 0.33049387 0.5747057 0.66658586 0.34418833]]

高级索引

import numpy as np

x = 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,25]]);

y1 = x[[0,1,3,4,2,0],[1,0,0,3,2,0]]; #一维整数索引
y2 = x[[[1,1],[2,3]],
[[0,3],[4,2]]] #多维整数索引
y3 = x[x > 7] #一维布尔索引
NaN = np.nan; #非数值NaN
a = np.array([np.nan,1,2+6j,np.nan,3+6j,4,5]);
x = np.arange(32).reshape(8,4);

print(y1);
print(y2);
print(y3);
print(NaN);
print(a);
print(np.isnan(a)); #过滤NaN元素 类似方法还有很多
print(~np.isnan(a));#布尔值取反
print (a[np.iscomplex(a)]); #过滤非复数元素
print(x);
#---------花式索引-------
print(x[[4,2,1,7]]); #顺序索引数组
print (x[[-4,-2,-1,-7]]); #倒序索引数组
print(np.ix_([1,5,7,2],[0,3,1,2],[0,3,1,2])); #生成一个索引器
print (x[np.ix_([1,5,7,2],[0,3,1,2])]); #多个索引数组

>>>
[ 2 6 16 24 13 1]

[[ 6 9]
[15 18]]

[ 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]

nan

[nan+0.j 1.+0.j 2.+6.j nan+0.j 3.+6.j 4.+0.j 5.+0.j]

[False True True False True True True]

[ True False False True False False False]

[2.+6.j 3.+6.j]

[[ 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]]

[[16 17 18 19]
[ 8 9 10 11]
[ 4 5 6 7]
[28 29 30 31]]

[[16 17 18 19]
[24 25 26 27]
[28 29 30 31]
[ 4 5 6 7]]

(array([[[1]],[[5]],[[7]],[[2]]]),array([[[0],[3],[1],[2]]]),array([[[0, 3, 1, 2]]]))

[[ 4 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]

数组属性

import numpy as np

a = 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,25]]);

print(type(a)); #数组数据类型
print(a.dtype); #数组元素数据类型
print(a.size); #数组尺寸,即数组元素总数
print(a.shape); #数组形状
print(a.itemsize); #每个元素占用字节数
print(a.ndim); #数组的维度数目
print(a.nbytes); #数组所有的数据消耗的字节数(不计算数组开销)

>>>
int32
25
(5, 5)
4
2
100

数组拼接

import numpy as np;
import math as m;

a = np.array([[80, 88], [82, 81], [84, 75], [86, 83], [75, 81]])
b = np.array([[80, 88], [82, 81], [84, 75], [86, 83], [75, 81]])
c = np.vstack((a,b)); #垂直拼接
d = np.hstack((a,b)); #水平拼接

print(c);
print(d);

>>>
[[80 88]
[82 81]
[84 75]
[86 83]
[75 81]
[80 88]
[82 81]
[84 75]
[86 83]
[75 81]]

[[80 88 80 88]
[82 81 82 81]
[84 75 84 75]
[86 83 86 83]
[75 81 75 81]]

广播

运算两个数组形状不相等时,自动触发广播机制

广播的规则:

  • 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
  • 输出数组的形状是输入数组形状的各个维度上的最大值。
  • 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
  • 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。

简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:

  • 数组拥有相同形状。
  • 当前维度的值相等。
  • 当前维度的值有一个是 1。

若条件不满足,抛出 "ValueError: frames are not aligned" 异常

http://www.runoob.com/numpy/numpy-broadcast.html 连接可以帮助理解广播机制

 

迭代数组

import numpy as np

a = np.arange(6).reshape(2,3);

print(a);
print('\n');
print(np.nditer(a));
print('\n');
print(a.T);
print('\n');

print("a:")
for x in np.nditer(a):
print(x,end=', ');
print('\n')

print("a.T:")
for x in np.nditer(a.T):
print(x, end=", ")
print('\n')

print("a.T.copy(order='F'):") #按列序优先
for x in np.nditer(a.T.copy(order='F')):
print(x, end=", ")
print('\n')

print("a,order='F':")
for x in np.nditer(a,order='F'):
print(x, end=", ")
print('\n')

print("a.T,order='F':")
for x in np.nditer(a.T,order='F'):
print(x, end=", ")
print('\n')

print("a.T.copy(order='C'):") #按行序优先
for x in np.nditer(a.T.copy(order='C')):
print(x, end=", ")
print('\n')

print("a.T,order='C':")
for x in np.nditer(a.T,order='C'):
print(x, end=", ")
print('\n')

print("a,order='C':")
for x in np.nditer(a,order='C'):
print(x, end=", ")
print('\n')

#修改数组中元素
print("op_flags=['readwrite']:")
'''
*“readonly”表示操作数只会被读取(默认)。
*“readwrite”表示操作数将被读写。
*“writeonly”表示只写入操作数。
'''
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print('修改后的数组是:')
print(a)

h = np.arange(0,60,5)
h = h.reshape(3,4)
print ('原始数组是:')
print (h)
print ('\n')
print ('修改后的数组是:')
for x in np.nditer(h, flags = ['external_loop'], order = 'F'):
print (x, end=", " )

>>>
[[0 1 2]
[3 4 5]]

[[0 3]
[1 4]
[2 5]]

a:
0, 1, 2, 3, 4, 5,
a.T:
0, 1, 2, 3, 4, 5,
a.T.copy(order='F'):
0, 1, 2, 3, 4, 5,
a,order='F':
0, 3, 1, 4, 2, 5,
a.T,order='F':
0, 1, 2, 3, 4, 5,
a.T.copy(order='C'):
0, 3, 1, 4, 2, 5,
a.T,order='C':
0, 3, 1, 4, 2, 5,
a,order='C':
0, 1, 2, 3, 4, 5,
op_flags=['readwrite']:
修改后的数组是:
[[ 0 2 4]
[ 6 8 10]]

原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],

数组操作

修改数组形状

reshape 不改变数据的条件下修改形状
flat 数组元素迭代器
flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ravel 返回展开数组

import numpy as np

'''
numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下: numpy.reshape(arr, newshape, order='C')
arr:要修改形状的数组
newshape:整数或者整数数组,新的形状应当兼容原有形状
order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。

numpy.ndarray.flat 是一个数组元素迭代器。

numpy.ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组。
ndarray.flatten(order='C')
order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。

numpy.ravel() 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组。
numpy.ravel(a, order='C')
order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。

'''

a = np.arange(8);
print('原始数据');
print(a);

b = a.reshape(4,2);
print('修改后的数组');
print(b);

print('原始数据循环');
for row in b:
print(row)

print('迭代后的数组');
for ele in b.flat:
print(ele)

print('展开的数组');
print(b.flatten())

print('展开的数组,F风格');
print(b.flatten(order='F'))

print('调用 ravel 函数之后:')
print(b.ravel());

print('调用 ravel 函数F风格之后:')
print(b.ravel(order='F'));

>>>

原始数据
[0 1 2 3 4 5 6 7]
修改后的数组
[[0 1]
[2 3]
[4 5]
[6 7]]
原始数据循环
[0 1]
[2 3]
[4 5]
[6 7]
迭代后的数组
0
1
2
3
4
5
6
7
展开的数组
[0 1 2 3 4 5 6 7]
展开的数组,F风格
[0 2 4 6 1 3 5 7]
调用 ravel 函数之后:
[0 1 2 3 4 5 6 7]
调用 ravel 函数F风格之后:
[0 2 4 6 1 3 5 7]

反转数组

transpose 对换数组的维度
ndarray.T 和 self.transpose() 相同
rollaxis 向后滚动指定的轴
swapaxes 对换数组的两个轴

import numpy as np

a = np.arange(12).reshape(3,4);

'''
numpy.transpose 函数用于对换数组的维度,格式如下:
numpy.transpose(arr, axes)
参数说明:
arr:要操作的数组
axes:整数列表,对应维度,通常所有维度都会对换。

numpy.ndarray.T 类似 numpy.transpose

rollaxis 函数向后滚动特定的轴到一个特定位置

swapaxes 函数用于交换数组的两个轴
'''

print('原数组a');
print(a);

print('transpose()后数组');
print(a.transpose());

print('ndarray.T后数组');
print(a.T);

# 创建了三维的 ndarray
b = np.arange(8).reshape(2, 2, 2)

print('原数组b:')
print(b)
print('\n')
# 将轴 2 滚动到轴 0(宽度到深度)

print('调用 rollaxis 函数:')
print(np.rollaxis(b, 2))
# 将轴 0 滚动到轴 1:(宽度到高度)
print('\n')

print('调用 rollaxis 函数:')
print(np.rollaxis(b, 2, 1))

print('调用 rollaxis 函数:')
print(np.rollaxis(b, 2, 2))

print ('调用 swapaxes 函数后的数组:')
print (np.swapaxes(b, 2, 0))
>>>

原数组a
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
transpose()后数组
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
ndarray.T后数组
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
原数组b:
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
调用 rollaxis 函数:
[[[0 2]
[4 6]]
[[1 3]
[5 7]]]
调用 rollaxis 函数:
[[[0 2]
[1 3]]
[[4 6]
[5 7]]]
调用 rollaxis 函数:
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]

#轴概念的描述
#轴其实就是数组的纬度,比如二维数组中第一纬度就是轴0,第二纬度就是轴1 .....
#下面是数组的访问方法:
#[[0,1]]
#0=>[0][0] 1=>[0][1]
#以数据1为例,[0]就是轴0,[1]就是轴1
#如果把数据的轴1换到轴0位置的得到的新数组为
#[[0],[1]]
#0=>[0][0] 1=>[1][0]

调用 swapaxes 函数后的数组:
[[[0 4]
[2 6]]
[[1 5]
[3 7]]]

修改数组纬度

broadcast 产生模仿广播的对象
broadcast_to 将数组广播到新形状
expand_dims 扩展数组的形状
squeeze 从数组的形状中删除一维条目

import numpy as np;

'''
numpy.broadcast
numpy.broadcast 用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。

numpy.broadcast_to
numpy.broadcast_to 函数将数组广播到新形状。它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。
'''

x = np.array([[1],[2],[3]]);
y = np.array([4, 5, 6]);

b = np.broadcast(x, y);

print('对 y 广播 x :');
r, c = b.iters;

print(b.iters);
print(next(r),next(c));
print(next(r),next(c));
print(next(r),next(c));
print(next(r),next(c));
print(next(r),next(c));
print(next(r),next(c));
print(next(r),next(c));
print(next(r),next(c));
print(next(r),next(c));
print('\n');

print('广播对象的形状:');
print(b.shape);
print('\n');

print('手动使用 broadcast 将 x 于 y 相加');
b = np.broadcast(x, y);
c = np.empty(b.shape);

print(c.shape);
print('\n');

print('调用 flat 函数:')
c.flat = [u + v for (u, v) in b];
print(c)
print('\n')

print(u + v for (u, v) in b)
print(c.flat)
print('\n')

print ('x 与 y 的和:')
print (x + y)

a = np.arange(4).reshape(1, 4)

print('原数组:')
print(a)
print('\n')

print('调用 broadcast_to 函数之后:')
print(np.broadcast_to(a, (4, 4)))

>>>
对 y 广播 x :
(, )
1 4
1 5
1 6
2 4
2 5
2 6
3 4
3 5
3 6

广播对象的形状:
(3, 3)

手动使用 broadcast 将 x 于 y 相加
(3, 3)

调用 flat 函数:
[[5. 6. 7.]
[6. 7. 8.]
[7. 8. 9.]]

<generator object <genexpr> at 0x0C492770>
<numpy.flatiter object at 0x0BF52BD0>

x 与 y 的和:
[[5 6 7]
[6 7 8]
[7 8 9]]

原数组:
[[0 1 2 3]]

调用 broadcast_to 函数之后:
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]

import numpy as np;

'''
numpy.expand_dims
numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状,函数格式如下:

numpy.squeeze
numpy.squeeze 函数从给定数组的形状中删除一维的条目,函数格式如下:
'''

x = np.array(([1, 2],[3, 4]));
print('数组 x:');
print(x);
print('\n');

y = np.expand_dims(x, axis = 0);
print('数组 y:');
print(y);
print('\n');

print('数组 x 和 y 的形状:');
print(x.shape,y.shape);
print('\n');

y = np.expand_dims(x, axis = 1);

print('在位置 1 插入轴之后的数组 y:');
print(y);
print('\n');

print('x.ndim 和 y.ndim:')
print(x.ndim, y.ndim)
print('\n')

print('x.shape 和 y.shape:')
print(x.shape, y.shape)
print('\n');

x = np.arange(9).reshape(1, 3, 3);

print('数组 x:');
print(x);
print('\n');
y = np.squeeze(x);

print('数组 y:');
print(y);
print('\n');

print('数组 x 和 y 的形状:');
print(x.shape, y.shape);
>>>

数组 x:
[[1 2]
[3 4]]

数组 y:
[[[1 2]
[3 4]]]

数组 x 和 y 的形状:
(2, 2) (1, 2, 2)

在位置 1 插入轴之后的数组 y:
[[[1 2]]
[[3 4]]]

x.ndim 和 y.ndim:
2 3

x.shape 和 y.shape:
(2, 2) (2, 1, 2)

数组 x:
[[[0 1 2]
[3 4 5]
[6 7 8]]]

数组 y:
[[0 1 2]
[3 4 5]
[6 7 8]]

数组 x 和 y 的形状:
(1, 3, 3) (3, 3)

连接数组

concatenate 连接沿现有轴的数组序列
stack 沿着新的轴加入一系列数组。
hstack 水平堆叠序列中的数组(列方向)
vstack 竖直堆叠序列中的数组(行方向)

import numpy as np;

'''
numpy.concatenate
numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组

numpy.stack
numpy.stack 函数用于沿新轴连接数组序列

numpy.hstack
numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组

numpy.vstack
numpy.vstack 是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。
'''

a = np.array([[1, 2],[3, 4]]);
print('第一个数组:');
print(a);
print('\n');

b = np.array([[5, 6],[7, 8]]);
print('第二个数组:');
print(b);
print('\n');

print('沿着轴0连接两个数组:');
print(np.concatenate((a,b)));
print('\n');

print('沿着轴1连接两个数组');
print(np.concatenate((a,b),axis = 1));

print('沿轴 0 堆叠两个数组:')
print(np.stack((a, b), 0))
print('\n')

print('沿轴 1 堆叠两个数组:')
print(np.stack((a, b), 1))
print('\n')

print ('水平堆叠:')
c = np.hstack((a,b))
print (c)
print ('\n')

print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)
>>>
第一个数组:
[[1 2]
[3 4]]

第二个数组:
[[5 6]
[7 8]]

沿着轴0连接两个数组:
[[1 2]
[3 4]
[5 6]
[7 8]]

沿着轴1连接两个数组
[[1 2 5 6]
[3 4 7 8]]

沿轴 0 堆叠两个数组:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]

沿轴 1 堆叠两个数组:
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]

水平堆叠:
[[1 2 5 6]
[3 4 7 8]]

竖直堆叠:
[[1 2]
[3 4]
[5 6]
[7 8]]

分割数组

split 将一个数组分割为多个子数组
hsplit 将一个数组水平分割为多个子数组(按列)
vsplit 将一个数组垂直分割为多个子数组(按行)

import numpy as np;

'''
numpy.split
numpy.split 函数沿特定的轴将数组分割为子数组

numpy.hsplit
numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。

numpy.vsplit
numpy.vsplit 沿着垂直轴分割,其分割方式与hsplit用法相同。
'''

a = np.arange(9);

print('第一个数组:');
print(a);
print('\n');

print('将数组分为三个大小相等的子数组:');
b = np.split(a, 3);
print(b);
print('\n');

print('将数组在一维数组中表明的位置分割:');
b = np.split(a, [0, 2]);
print(b);
print('\n');

print ('水平拆分后:');
b = np.hsplit(a, 3);
print(b);
print('\n');

print('d原数组');
d = np.arange(16).reshape(4,4)
print (d);
print('\n');

print ('竖直拆分后:');
b = np.vsplit(d,2);
print (b);
print('\n');

>>>
第一个数组:
[0 1 2 3 4 5 6 7 8]

将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]

将数组在一维数组中表明的位置分割:
[array([], dtype=int32), array([0, 1]), array([2, 3, 4, 5, 6, 7, 8])]

水平拆分后:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]

d原数组
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]

竖直拆分后:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]

数组元素的添加与删除

resize 返回指定形状的新数组
append 将值添加到数组末尾
insert 沿指定轴将值插入到指定下标之前
delete 删掉某个轴的子数组,并返回删除后的新数组
unique 查找数组内的唯一元素

import numpy as np;

'''
numpy.resize 函数返回指定大小的新数组。
如果新数组大小大于原始大小,则包含原始数组中的元素的副本。

numpy.append
numpy.append 函数在数组的末尾添加值。追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。
'''

a = np.array([[1, 2, 3], [4, 5, 6]]);

print('第一个数组');
print(a);
print('\n');

print('第一个数组的形状:');
print(a.shape);
print('\n');

b = np.resize(a, (3, 2));

print('第二个数组:');
print(b);
print('\n');

print('第二个数组的形状:');
print(b.shape);
print('\n');

# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了

print('修改第二个数组的大小:');
b = np.resize(a, (3, 3));
print(b);
print('\n')

print('向数组添加元素:')
print(np.append(a, [7, 8, 9]))
print('\n')

print('沿轴 0 添加元素:')
print(np.append(a, [[7, 8, 9]], axis=0))
print('\n')

print('沿轴 1 添加元素:')
print(np.append(a, [[5, 5, 5], [7, 8, 9]], axis=1))

>>>

第一个数组
[[1 2 3]
[4 5 6]]

第一个数组的形状:
(2, 3)

第二个数组:
[[1 2]
[3 4]
[5 6]]

第二个数组的形状:
(3, 2)

修改第二个数组的大小:
[[1 2 3]
[4 5 6]
[1 2 3]]

向数组添加元素:
[1 2 3 4 5 6 7 8 9]

沿轴 0 添加元素:
[[1 2 3]
[4 5 6]
[7 8 9]]

沿轴 1 添加元素:
[[1 2 3 5 5 5]
[4 5 6 7 8 9]]

import numpy as np;

'''
numpy.insert
numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。

numpy.delete
numpy.delete 函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开。
'''

a = np.array([[1, 2, 3], [4, 5, 6]]);

print('第一个数组');
print(a);
print('\n');

print('第一个数组的形状:');
print(a.shape);
print('\n');

b = np.resize(a, (3, 2));

print('第二个数组:');
print(b);
print('\n');

print('第二个数组的形状:');
print(b.shape);
print('\n');

# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了

print('修改第二个数组的大小:');
b = np.resize(a, (3, 3));
print(b);
print('\n')

print('向数组添加元素:')
print(np.append(a, [7, 8, 9]))
print('\n')

print('沿轴 0 添加元素:')
print(np.append(a, [[7, 8, 9]], axis=0))
print('\n')

print('沿轴 1 添加元素:')
print(np.append(a, [[5, 5, 5], [7, 8, 9]], axis=1))
print('\n')

a = np.arange(12).reshape(3, 4)

print('第一个数组:')
print(a)
print('\n')

print('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print(np.delete(a, 5))
print('\n')

print('删除第二列:')
print(np.delete(a, 1, axis=1))
print('\n')

print('包含从数组中删除的替代值的切片:')
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(np.delete(a, np.s_[::2]))

>>>

第一个数组
[[1 2 3]
[4 5 6]]

第一个数组的形状:
(2, 3)

第二个数组:
[[1 2]
[3 4]
[5 6]]

第二个数组的形状:
(3, 2)

修改第二个数组的大小:
[[1 2 3]
[4 5 6]
[1 2 3]]

向数组添加元素:
[1 2 3 4 5 6 7 8 9]

沿轴 0 添加元素:
[[1 2 3]
[4 5 6]
[7 8 9]]

沿轴 1 添加元素:
[[1 2 3 5 5 5]
[4 5 6 7 8 9]]

第一个数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 0 1 2 3 4 6 7 8 9 10 11]

删除第二列:
[[ 0 2 3]
[ 4 6 7]
[ 8 10 11]]

包含从数组中删除的替代值的切片:
[ 2 4 6 8 10]

import numpy as np;

'''
numpy.unique
numpy.unique 函数用于去除数组中的重复元素。
'''

import numpy as np

a = np.array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])

print('第一个数组:')
print(a)
print('\n')

print('第一个数组的去重值:')
u = np.unique(a)
print(u)
print('\n')

print('去重数组的索引数组:')
u, indices = np.unique(a, return_index=True)
print(indices)
print('\n')

print('我们可以看到每个和原数组下标对应的数值:')
print(a)
print('\n')

print('去重数组的下标:')
u, indices = np.unique(a, return_inverse=True)
print(u)
print('\n')

print('下标为:')
print(indices)
print('\n')

print('使用下标重构原数组:')
print(u[indices])
print('\n')

print('返回去重元素的重复数量:')
u, indices = np.unique(a, return_counts=True)
print(u)
print(indices)

>>>

第一个数组:
[5 2 6 2 7 5 6 8 2 9]

第一个数组的去重值:
[2 5 6 7 8 9]

去重数组的索引数组:
[1 0 2 4 7 9]

我们可以看到每个和原数组下标对应的数值:
[5 2 6 2 7 5 6 8 2 9]

去重数组的下标:
[2 5 6 7 8 9]

下标为:
[1 0 2 0 3 1 2 4 0 5]

使用下标重构原数组:
[5 2 6 2 7 5 6 8 2 9]

返回去重元素的重复数量:
[2 5 6 7 8 9]
[3 2 2 1 1 1]

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄