基本命令
1.数组类型ndarray
Numpy提供了一个N维数组类型ndarray,它描述了相同类型的"items"的集合。
属性名字 | 属性解释 |
---|---|
ndarray.shape | 数组维度的元组 |
ndarray.ndim | 数组维数(shape元组有几个数字,它就是几) |
ndarray.size | 数组中的元素数量 |
ndarray.itemsize | 一个数组元素的长度(字节) |
ndarray.dtype | 元素的类型 |
import numpy as np
score = np.array([[80, 89, 86, 67, 79],
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74],
[91, 91, 90, 67, 69],
[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84],
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]])
print(type(score))
print(score.shape)
print(score.dtype)
2.基本操作
2.2生成数组
1、生成0和1的数组
np.zeros(shape=(3, 4), dtype="float32") # 生成一组0
np.ones(shape=[2, 3], dtype=np.int32) # 生成一组1
np.empty((3,4)) # 创建全空数组,其实每个值都是接近于零的数
np.arange(4).reshape((2,2))#从零开始
2、从现有数组生成
data1 = np.array(score) # 深拷贝
data2 = np.asarray(score) # 浅拷贝,不占用内存
data3 = np.copy(score) # 深拷贝
3、生成固定范围的数组
np.linspace(0, 10, 5) # 生成[0,10]之间等距离的5个数
np.arange(0, 11, 5) # [0,11),5为步长生成数组
4、生成随机数组
# 生成均匀分布的一维数组[low,high)
data1 = np.random.uniform(low=-1, high=1, size=1000000)
# 生成正态分布的一维数组,loc:均值;scale:标准差
data2 = np.random.normal(loc=1.75, scale=0.1, size=1000000)
data3 = np.random.rand(3,4,5)
5、更改数组
# 创建线段型数据
a = np.linspace(1,10,20) # 开始端1,结束端10,且分割成20个数据,生成线段
b = a.reshape((5,4))
'''
[[ 1. 1.47368421 1.94736842 2.42105263]
[ 2.89473684 3.36842105 3.84210526 4.31578947]
[ 4.78947368 5.26315789 5.73684211 6.21052632]
[ 6.68421053 7.15789474 7.63157895 8.10526316]
[ 8.57894737 9.05263158 9.52631579 10. ]]
'''
# 生成均匀分布的一组数[low,high)
data1 = np.random.uniform(low=-1, high=1, size=1000000)
# 生成正态分布的一组数,loc:均值;scale:标准差
data2 = np.random.normal(loc=1.75, scale=0.1, size=1000000)
data3 = np.random.rand(3,4,5)
2.3数组的索引、切片
stock_change = np.random.normal(loc=0, scale=1, size=(8, 10))
# 获取第一个股票的前3个交易日的涨跌幅数据
print(stock_change[0, :3])
a1[1, 0, 2] = 100000
注意:如果你想要得到的是ndarray切片的一份副本而非视图,就需要明确地进行复制操作,例如arr[5:8].copy()。
In [60]: arr = np.arange(10)
In [61]: arr
Out[61]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [64]: arr[5:8] = 12
In [65]: arr
Out[65]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
如上所示,当你将一个标量值赋值给一个切片时(如arr[5:8]=12),该值会自动传播。跟列表最重要的区别在于,数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。
作为例子,先创建一个arr的切片:
In [66]: arr_slice = arr[5:8]
In [67]: arr_slice
Out[67]: array([12, 12, 12])
In [68]: arr_slice[1] = 12345
In [69]: arr
Out[69]: array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
2.4形状修改
stock_change = stock_change.reshape((10, 8)) # 返回新的ndarray,原始数据没有改变
stock_change.resize((10, 8)) # 没有返回值,对原始的ndarray进行了修改
stock_change.flatten() # 变成一维数组
stock_change.T # 转置 行变成列,列变成行
# A = np.array([1,1,1]) np.newaxis插入新维度
A[np.newaxis,:] # [1 1 1]变为[[1 1 1]]
A[:,np.newaxis]
'''
[[1]
[1]
[1]]
'''
2.5类型修改
stock_change.astype("int32")
stock_change.tostring() # ndarray序列化到本地
2.6数组去重
#1
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
temp = np.unique(temp) #[1 2 3 4 5 6] 自动排序
#2
arr = np.array([[7, 8], [3, 3], [5, 4]]) #要求是 arr 里面是相同的维数。
result3 = np.unique(arr)
print(result3) # [3 4 5 7 8]
#3
arr = np.array([[7, 8], [3, 3], [5, 4, 9, 0]])
result3 = np.unique(arr)
print(result3) # [list([3, 3]) list([5, 4, 9, 0]) list([7, 8])]
3.运算
统计运算
1.统计指标函数
min,max,mean(均值),median(中位数),var(方差),std(标准差)
temp.max(axis=0) #axis=0行,axis=1列
np.max(temp, axis=1)
返回最大值、最小值的位置
np.argmax(tem,axis=-1)
np.argmin(tem,axis=-1)
函数 | 功能 |
---|---|
np.argmin(a, axis=None, out=None) | 最小元素索引 |
np.argmax() | 最大元素索引 |
np.mean() | 求整个矩阵的均值 |
np.average() | 求整个矩阵的均值 |
ndarray.mean() | 求整个矩阵的均值 |
np.median() | 中位数 |
数组与数组的运算
1.基本运算
大小相等的数组之间的任何算术运算都会将运算应用到元素级:
In [51]: arr = np.array([[1., 2., 3.], [4., 5., 6.]])
In [52]: arr
Out[52]:
array([[ 1., 2., 3.],
[ 4., 5., 6.]])
In [53]: arr * arr
Out[53]:
array([[ 1., 4., 9.],
[ 16., 25., 36.]])
In [54]: arr - arr
Out[54]:
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
数组与标量的算术运算会将标量值传播到各个元素:
In [55]: 1 / arr
Out[55]:
array([[ 1. , 0.5 , 0.3333],
[ 0.25 , 0.2 , 0.1667]])
In [56]: arr ** 0.5
Out[56]:
array([[ 1. , 1.4142, 1.7321],
[ 2. , 2.2361, 2.4495]])
大小相同的数组之间的比较会生成布尔值数组:
In [57]: arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
In [58]: arr2
Out[58]:
array([[ 0., 4., 1.],
[ 7., 2., 12.]])
In [59]: arr2 > arr
Out[59]:
array([[False, True, False],
[ True, False, True]], dtype=bool)
元素相乘:multply()
矩阵相乘:dot()、matmul()、’@’
’ * ': 是特别的。在数组操作中,作为元素相乘;在矩阵操作中作为矩阵相乘。
2.广播机制(位置相乘)
执行broadcast的前提在于,两个nadarray执行的是element-wise的运算,Broadcast机制的功能是为了方便不同形状的ndarray(numpy库的核心数据结构)进行数学运算。
当操作两个数组时,numpy会逐个比较它们的shape(构成的元组tuple),只有在下述情况下,两个数组才能够进行数组与数组的运算。
- 维度相等
- shape(其中相对应的一个地方为1)
例如
import numpy as np
a=np.array([1,2,3])
b1=np.array([2,2,2])
b2=2
print(a*b1) # [2 4 6]
print(a*b2) # [2 4 6]
data1 = np.random.rand(4,5)
data2 = np.random.rand(5)
data3 = np.random.rand(4)
print(data1+data2) # ok
print(data1+data3) #erro
3.矩阵运算
英文matrix和array的区别是矩阵必须是2维的,但是array可以是多维的。
np.mat() 将数组转换成矩阵类型
矩阵乘法规则(M行,N列)x (N行,L列) = (M行,L列)
np.dot函数主要有两个功能,向量点积和矩阵乘法,这里我就简单列举了三种最常用到的情况
# 1.a和b都是二维矩阵,此时dot就是进行的矩阵乘法运算
a = np.random.randint(0, 10, size = (2, 5))
b = np.random.randint(0, 10, size = (5, 3))
print(np.dot(a, b).shape) #大小(2, 3)
# 2.a和b都是一维的向量,此时dot就是进行向量点积运算
a = np.array([1, 2, 3, 4, 5])
b = np.array([6, 7, 8, 9, 10])
print(np.dot(a, b)) #130
# 3.a为二维矩阵,b为一维向量,这时b会被当做一维矩阵进行计算。进行运算时,会首先将后面一项进行自动转置操作,之后再进行乘法运算。
a = np.random.randint(0,10, size = (5,5))
b = np.array([1,2,3,4,5])
print("the shape of a is " + str(a.shape))# (5, 5)
print("the shape of b is " + str(b.shape))# (5,) 在运算时是(5,1)
print(np.dot(a, b).shape) #(5,) 但是看起来是(1,5)
np.matmul是两个数组的矩阵相乘
如果某一个参数是N ( N > 2 ) 维的,该参数被理解为一些矩阵(参数的最后两个维数为矩阵维数)的stack,而且计算时会相应的广播
a = np.arange(2*2*4).reshape((2,2,4)) # 当成2个(2,4)
b = np.arange(2*2*4).reshape((2,4,2))# 当成2个(4,2)
c = np.arange(1*2*4).reshape((1,4,2))# 进行广播,当成2个(4,2)
np.matmul(a,b) #(2,2,2)
np.matmul(a,c) #(2,2,2)
print(np.dot(a,b).shape) # (2, 2, 2, 2)
print(np.dot(a,c).shape) # (2, 2, 2, 2)
print(np.matmul(b,a).shape) # (2, 4, 4)
print(np.matmul(c,a).shape) # (2, 4, 4)
print(np.dot(b,a).shape) # (2, 4, 2, 4)
print(np.dot(c,a).shape) # (1, 4, 2, 4)
matmul与dot的差异主要在两个方面:
(1)matmul不允许乘标量
(2)stack的矩阵将矩阵按元素对待被一起广播
4.杂项
合并、分割
合并
numpy.hstack #水平拼接
numpy.vstack #竖拼接
numpy.concatenate((a1,a2),axis=0) # axis=0纵向合并
当axis的值为0的时候,将会以列作为查找单元,
当axis的值为1的时候,将会以行作为查找单元。
分割
numpy.split(x,3,axis=1) # 分三份 纵向分割
numpy.split(x,[3,4,6,10]) # 按索引分割
# 横向分割
np.vsplit(x,3)) # 等价于np.split(A,3,axis=0)
# 纵向分割
np.hsplit(x,2)) # 等价于np.split(A,2,axis=1)
函数 | 功能 |
---|---|
np.cumsum() | 累加 |
np.diff(x,axis=1) | 累差运算 |
np.sort() | 排序 |
ndarray.T | 矩阵转置 |
np.sqrt() | 开方 |
np.abs(arr) | 求绝对值 |
np.clip(A,5,9) | 矩阵A中的元素,全部大于5小于9 |
np.around([-0.6,1.2798,2.357,9.67,13], decimals=0) | 取指定位置的精度,小数点后几位;decimals=-2时小数点前两位,不足部分为0 |
np.floor() | 向下取整 |
np.ceil() | 向上取整 |
np.add(x, y) | 计算两个数组的和 |
参考
1.https://docs.hwl.cool/python/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/numpy.html#%E4%BB%8B%E7%BB%8D
2.https://github.com/iamseancheney/python_for_data_analysis_2nd_chinese_version/blob/master/%E7%AC%AC04%E7%AB%A0%20NumPy%E5%9F%BA%E7%A1%80%EF%BC%9A%E6%95%B0%E7%BB%84%E5%92%8C%E7%9F%A2%E9%87%8F%E8%AE%A1%E7%AE%97.md