numpy基础篇
numpy数组的创建
numpy 主要数据类型为ndarray,创建方法为:numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
其中 object 为数组或者嵌套数据,一般为list类型 , dtype指定数据类型 ,ndmin指定数据的最小维度
import numpy as np
data = np.array([[1,2,3],[4,5,6]])
data
array([[1, 2, 3],
[4, 5, 6]])
当数组object的维度小于ndmin时,会自自动补充维度
data1 = np.array([1,2,3], ndmin =2)
data1
array([[1, 2, 3]])
numpy常用的数据类型及其相关的信息查看
- 常用的数据类型,int8,int16,int32,int64 float16,float32, float64
- 查看数据类型
data1.dtype
dtype('int32')
- 查看数组的维度 和总数量
data1.shape,data1.size
((1, 3), 3)
- 查看数组的维数
data2 = np.arange(24)
data3 = data2.reshape(2,3,4)
data2.ndim, data3.ndim
(1, 3)
numpy 中的切片
data4 = np.arange(12)
s = slice(2, 7, 2)
s, data4[s], data4[2:7:2]
(slice(2, 7, 2), array([2, 4, 6]), array([2, 4, 6]))
多维数组的切片方式,每个维度的切割用逗号分隔;
也可以通过冒号分隔切片参数 start:stop:step 来进行切片操作: 步长step 默认为1
冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。
data5 = np.arange(24).reshape([2,3,4])
data5
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
data5[0:1,1:2,2:3]
array([[[6]]])
numpy广播
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
#当两个数组维度相同或者符合计算要求时,不会触发广播机制,只有维度不符合正常的计算时,才会触发广播机制
data6 = np.array([[ 0, 1, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
data7 = np.array([1,2,3])
data6 + data7
array([[ 1, 3, 3],
[11, 12, 13],
[21, 22, 23],
[31, 32, 33]])
广播的规则:广播的规则:
让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
输出数组的形状是输入数组形状的各个维度上的最大值。
如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
数组拥有相同形状。
当前维度的值相等。
当前维度的值有一个是 1。
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
numpy迭代数组
data8 = np.arange(12).reshape(3,4)
data8
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
逐个元素遍历,默认行序优先
for x in np.nditer(data8):
print(x)
0
1
2
3
4
5
6
7
8
9
10
11
也可以使用转置,使其列序优先
for x in np.nditer(data8.T):
print(x)
0
1
2
3
4
5
6
7
8
9
10
11
很明显,原数据和他的转置在内存中的存储方式是一样的
使用复制解决这个问题
for x in np.nditer(data8.T.copy(order ="C")):
print(x)
0
4
8
1
5
9
2
6
10
3
7
11
修改数组形状
- 不改变数组的数字,返回修改数组的维度
data9 = np.arange(12)
data10 = data9.reshape([6,2])
data10
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11]])
- 数组扁平处理
data10.flatten()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
- 返回扁平数组的一个迭代器
data10.flat
<numpy.flatiter at 0x23f512e5880>
- 对换数组的维度:如对data10的行列进行调换
data10.transpose([1,0])
array([[ 0, 2, 4, 6, 8, 10],
[ 1, 3, 5, 7, 9, 11]])
- 从给定数组的形状中删除一维的条目,函数格式如下:numpy.squeeze(arr, axis),axis必须为维度为1的维度,否则会报错,一般需要先用shape查看维度分布
data11 = np.arange(9).reshape(1,3,3)
print ('数组 data11:')
print (data11)
print ('\n')
y = np.squeeze(data11,axis =0)
print ('数组 y:')
print (y)
print ('\n')
print ('数组 data11 和 y 的形状:')
print (data11.shape, y.shape)
数组 data11:
[[[0 1 2]
[3 4 5]
[6 7 8]]]
数组 y:
[[0 1 2]
[3 4 5]
[6 7 8]]
数组 data11 和 y 的形状:
(1, 3, 3) (3, 3)
连接数组
- 形式如下:numpy.concatenate((a1, a2, …), axis)
参数说明:
a1, a2, …:相同类型的数组
axis:沿着它连接数组的轴,默认为 0
concatenate() 函数的结果不会增加数据的维度个数,不会从二维变成三维
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))
第一个数组:
[[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]]
分割数组
numpy.split
numpy.split 函数沿特定的轴将数组分割为子数组,格式如下:
numpy.split(ary, indices_or_sections, axis)
参数说明:
ary:被分割的数组
indices_or_sections:果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)
axis:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分
a = np.arange(9)
print ('第一个数组:')
print (a)
print ('\n')
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('\n')
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
第一个数组:
[0 1 2 3 4 5 6 7 8]
将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
将数组在一维数组中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
数组元素的添加与删除
形式: numpy.append(arr, values, axis=None)
参数说明:
arr:输入数组
values:要向arr添加的值,需要和arr形状相同(除了要添加的轴)
axis:默认为 None。当axis无定义时,是横向加成,返回总是为一维数组!当axis有定义的时候,分别为0和1的时候。当axis有定义的时候,分别为0和1的时候(列数要相同)。当axis为1时,数组是加在右边(行数要相同)。
实例
d1 = np.arange(12).reshape([2,2,3])
d1
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
d2 = np.append(d1,[12, 13, 16])
d2
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16])
与np.concatenate不同的是,其先按维度把数据打平,再进行append,
numpy.insert
numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
numpy.insert(arr, obj, values, axis)
参数说明:
arr:输入数组
obj:在其之前插入值的索引
values:要插入的值
axis:沿着它插入的轴,如果未提供,则输入数组会被展开
如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
a = np.array([[1,2],[3,4],[5,6]])
print ('第一个数组:')
print (a)
print ('\n')
print ('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print (np.insert(a,3,[11,12]))
print ('\n')
print ('传递了 Axis 参数。 会广播值数组来配输入数组。')
print ('沿轴 0 广播:')
print (np.insert(a,1,[11],axis = 0))
print ('\n')
print ('沿轴 1 广播:')
print (np.insert(a,1,11,axis = 1))
第一个数组:
[[1 2]
[3 4]
[5 6]]
未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 1 2 3 11 12 4 5 6]
传递了 Axis 参数。 会广播值数组来配输入数组。
沿轴 0 广播:
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
沿轴 1 广播:
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
numpy中的random模块
import numpy as np
- np.random.rand()根据给定的维度,生成指定指定维度,值域为[0,1)的数组
np.random.rand(2,3)
array([[0.6287947 , 0.39817228, 0.00665975],
[0.61628815, 0.2680968 , 0.66216574]])
- np.random.randn() 与上面方法一样,只是生成的数据服从正太分布
np.random.randn(3,4)
array([[ 0.40818378, 0.43111242, -0.91678831, 1.23631489],
[-1.47057993, 0.35138769, 0.05062891, -0.1615172 ],
[-0.45244405, 0.36723057, 0.3361508 , -1.59899812]])
- numpy.random.randint(low, high=None, size=None, dtype=‘l’) 返回[low.high)范围指定大小size的数组,数据类型为long
np.random.randint(0,5,(2,3))
array([[4, 2, 0],
[0, 0, 4]])
- numpy.random.choice(a, size=None, replace=True, p=None) 从指定的数组中随机选取一个随机数组,有点绕,看例子,a为数组或者整数,当a为数组时,生成的随机数组中的数字从这个数组中产生,当a为数字时,生成的数据为整数[0,a), p为一个概率数组,表示a中每个数字出现的概率。
np.random.choice(5,size=3)
array([3, 3, 0])
np.random.choice(10,size=20)
array([4, 0, 5, 0, 5, 1, 2, 3, 7, 9, 8, 3, 2, 6, 2, 5, 4, 2, 4, 9])
np.random.choice([2,6,7,9],10)
array([2, 7, 2, 6, 9, 6, 9, 6, 2, 9])
np.random.choice([2,6,7,9],20,p=[0.7,0.2,0.05,0.05])
array([7, 2, 2, 6, 2, 2, 6, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 6])
此函数在自然语言处理,增强数据,随机去掉某些字很好用
- numpy.random.seed() 与其他函数一起用,连体婴 ,当设置相同的种子时,生成随机数组就一样,不设置,或者不相同,随机数组就不一样
np.random.seed(0)
np.random.rand(5)
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.seed(1676)
np.random.rand(5)
array([0.39983389, 0.29426895, 0.89541728, 0.71807369, 0.3531823 ])
np.random.seed(1676)
np.random.rand(5)
array([0.39983389, 0.29426895, 0.89541728, 0.71807369, 0.3531823 ])
np.random.rand(5)
array([0.96537912, 0.46218718, 0.71936643, 0.50402396, 0.90558239])