啃书《利用python进行数据分析》NumPy部分
这个系列就是认真看看《利用python进行数据分析》这本书,对于书中的部分重要的章节,自己敲代码理解,进行基础知识的巩固吧~属于是一字一句的看了的,对书中的内容有自己的理解,(也有不太明确的地方有标注出来 !)欢迎一起讨论!
文章目录
Numpy部分
ndarray多维数组对象
ndarray的shape,dtype属性
import numpy as np
#
data=np.random.randn(2,3)
data*10
Out[7]:
array([[ 14.27184059, -13.59751785, -13.59737187],
[ 0.63136249, 11.61651414, 18.1426275 ]])
data
Out[8]:
array([[ 1.42718406, -1.35975179, -1.35973719],
[ 0.06313625, 1.16165141, 1.81426275]])
data+data
Out[9]:
array([[ 2.85436812, -2.71950357, -2.71947437],
[ 0.1262725 , 2.32330283, 3.6285255 ]])
data.shape
Out[10]: (2, 3)
data.dtype
Out[11]: dtype('float64')
生成ndarray
ndarray的ndim属性
# 生成ndarray
data1=[6,7.5,9,0,1]
arr1=np.array(data1)
arr1
Out[15]: array([6. , 7.5, 9. , 0. , 1. ])
data2=[[1,2,3,4],[5,6,7,8]]
arr2=np.array(data2)
arr2
Out[18]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
arr2.ndim
Out[19]: 2
arr2.shape
Out[20]: (2, 4)
arr1.dtype
Out[21]: dtype('float64')
arr2.dtype
Out[23]: dtype('int32')
np.zeros(10)
Out[24]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros((3,6))
Out[25]:
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
np.empty((2,3,2))
Out[26]:
array([[[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.]]])
np.arange(15)
Out[27]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
总结
函数名 | 描述 |
---|---|
np.array() | 括号里可以是列表,元组,数组以及其他序列,将其转化为ndarray |
np.arange() | python内建函数range的数组版,返回一个数组。括号里接收一个数值n,生成0到n-1的一维数组 |
np.ones() | 括号里面是要生成数组的形状,一般用元组表示形状。 根据给定形状和数据类型生成全1数组 |
np.ones_like() | 括号里接受的是数组,根据传入的数组的形状生成全1数组。 |
np.zeros() | 同上,只不过生成全0数组 |
np.zeros_like() | 同上 |
np.empty() | 同上,只不过生成没有初始化的空数组 |
np.empty_like() | 同上 |
np.full() | 同上,括号里传入形状和指定数X,以这个形状生成全X数组 |
np.full_like() | 同上,括号传入数组和指定数 |
np.eye(),np.identity() | 生成一个N*N矩阵,对角线是1,其余是0 |
在上述生成ndarray方法中,都可以在括号里传入参数dtype=’ '来指定数据类型
np.ones(3)
Out[35]: array([1., 1., 1.])
np.ones((3,4))
Out[36]:
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
np.ones([3,5])
Out[37]:
array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
np.ones_like(arr2)
Out[38]:
array([[1, 1, 1, 1],
[1, 1, 1, 1]])
np.full((2,3),1)
Out[39]:
array([[1, 1, 1],
[1, 1, 1]])
np.full((2,3),6)
Out[40]:
array([[6, 6, 6],
[6, 6, 6]])
np.full_like(arr2,6)
Out[41]:
array([[6, 6, 6, 6],
[6, 6, 6, 6]])
np.full_like(arr2,6,dtype='int32')
Out[43]:
array([[6, 6, 6, 6],
[6, 6, 6, 6]])
np.full_like(arr2,6,dtype='float32')
Out[44]:
array([[6., 6., 6., 6.],
[6., 6., 6., 6.]], dtype=float32)
np.eye(5)
Out[45]:
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
np.identity(4)
Out[46]:
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
Numpy数据转换
原数组.astype(要转换成为的数据类型)
arr1=np.array([1,2,3],dtype=np.float64)
arr2=np.array([1,2,3],dtype=np.int32)
arr1.dtype
Out[49]: dtype('float64')
arr2.dtype
Out[50]: dtype('int32')
arr=np.array([1,2,3,4,5])
arr.dtype
Out[52]: dtype('int32')
float_arr=arr.astype(np.float64)
float_arr.dtype
Out[54]: dtype('float64')
arr=np.array([3.7,-1.4,-3.5,0.5])
arr
Out[56]: array([ 3.7, -1.4, -3.5, 0.5])
arr.astype(np.int32)
Out[57]: array([ 3, -1, -3, 0])
numeric_strings=np.array(['1.23','4.32','-9.6'],dtype=np.string_)
numeric_strings.astype(float)
Out[59]: array([ 1.23, 4.32, -9.6 ])
ndarray的数据类型dtype有很多,在转换时也可以用类型代码表示
int_array=np.arange(10)
calibers=np.array([.22,.270,.33,.39])
int_array.astype(calibers.dtype)
Out[63]: array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
empty_uint32=np.empty(8,dtype='u4')
empty_uint32
Out[65]:
array([3264175145, 1070344437, 343597384, 1070679982, 1374389535,
1070931640, 2405181686, 1071183298], dtype=uint32)
Numpy数组运算
arr=np.array([[1.,2.,3.],[4.,5.,6.]])
arr
Out[67]:
array([[1., 2., 3.],
[4., 5., 6.]])
arr*arr
Out[68]:
array([[ 1., 4., 9.],
[16., 25., 36.]])
arr-arr
Out[69]:
array([[0., 0., 0.],
[0., 0., 0.]])
1/arr
Out[70]:
array([[1. , 0.5 , 0.33333333],
[0.25 , 0.2 , 0.16666667]])
arr**0.5
Out[71]:
array([[1. , 1.41421356, 1.73205081],
[2. , 2.23606798, 2.44948974]])
arr2=np.array([[0.,4.,1],[7.,2.,12].])
File "<ipython-input-72-33c3182e654a>", line 1
arr2=np.array([[0.,4.,1],[7.,2.,12].])
^
SyntaxError: invalid syntax
arr2=np.array([[0.,4.,1],[7.,2.,12.]])
arr2>arr1
Out[74]:
array([[False, True, False],
[ True, False, True]])
总结:
同形状的数组运算:一一对应
数组与一个数字的计算:数字与数组元素一对多
基础索引与切片
arr=np.arange(10)
arr
Out[76]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr[5]
Out[77]: 5
arr[5:8]
Out[78]: array([5, 6, 7])
arr[5:8]=12
arr
Out[80]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
由上代码,可以看出 ,对 基础切片或索引的修改直接反映在原数组上
arr_slice=arr[5:8]
arr_slice
Out[82]: array([12, 12, 12])
arr_slice[1]=12345
arr
Out[84]:
array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8,
9])
由上代码可以看出,即便将切片赋值给了另一个变量,这个变量还是指向原来的视图,对这个变量的修改,也会映射到原数组上
arr=np.arange(10)
arr
Out[87]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr_copy=arr[5:8].copy()
arr_copy[1]=12345
arr_copy
Out[91]: array([ 5, 12345, 7])
arr
Out[92]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
由上代码,可知,如果想要切片的拷贝,而不是视图的话,要显性复制这个数组。arr[5:8].copy()
#将数组赋值给另一个数组后
arr=np.arange(10)
arr1=np.arange(10)
arr2=arr1
arr2[5:8]=12
arr1
Out[97]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
arr2
Out[98]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
#将列表赋值给另一个列表,也没有用
a=[1,2,3]
b=a
b[1]=999
a
Out[105]: [1, 999, 3]
b
Out[106]: [1, 999, 3]
高维数组的切片与索引
arr2d=np.array([[1,2,3],[4,3,6],[7,8,9]])
arr2d[2]
Out[115]: array([7, 8, 9])
#单个元素可以通过递归方式获得
arr2d[0][2]
Out[116]: 3
#传递一个索引的逗号分隔列表去获取
arr2d[0,2]
Out[117]: 3
关于axis:0轴是“行”,1轴是“列”
arr3d=np.arange(12).reshape(2,2,3)
arr3d
Out[122]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
arr3d[0]
Out[123]:
array([[0, 1, 2],
[3, 4, 5]])
old_values=arr3d.copy()
arr3d[0]=42
arr3d
Out[126]:
array([[[42, 42, 42],
[42, 42, 42]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
arr3d=old_values
arr3d
Out[128]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
arr3d[1,0]
Out[129]: array([6, 7, 8])
#切片
arr3d=np.arange(36).reshape(3,4,3)
arr3d
Out[132]:
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]],
[[24, 25, 26],
[27, 28, 29],
[30, 31, 32],
[33, 34, 35]]])
arr3d[0:2,1:3,0:2]
Out[133]:
array([[[ 3, 4],
[ 6, 7]],
[[15, 16],
[18, 19]]])
总结:
ndarray基本索引与切片的思想就是:用一个列表表示选择对数组的切皮或索引位置选择;用逗号来分隔维度;冒号代表切片,数字代表索引
[axis=0轴上的操作,axis=1轴上的操作,axis=2轴上的操作,…]
布尔索引
跟着书上敲代码:
names=np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
data=np.random.randn(7,4)
names
Out[136]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='<U4')
data
Out[137]:
array([[ 1.66189273, -1.74527032, -0.14516128, 1.13129175],
[ 0.57533365, 1.69365588, -1.05694541, -0.41405561],
[-0.18698056, -0.12247711, 1.01875469, 0.62176455],
[ 0.95455323, 1.76981728, -0.50373742, 1.24920993],
[ 0.88518599, 1.44812978, 0.18516454, -0.82940688],
[ 0.22833207, 2.16216305, -1.05428154, -0.71741654],
[ 2.15067166, -2.10548264, 0.44120789, 0.1395501 ]])
names=='Bob'
Out[138]: array([ True, False, False, True, False, False, False])
data[names=='Bob']
Out[139]:
array([[ 1.66189273, -1.74527032, -0.14516128, 1.13129175],
[ 0.95455323, 1.76981728, -0.50373742, 1.24920993]])
data[names=='Bob',2:]
Out[140]:
array([[-0.14516128, 1.13129175],
[-0.50373742, 1.24920993]])
data[~(names=='Bob')]
Out[141]:
array([[ 0.57533365, 1.69365588, -1.05694541, -0.41405561],
[-0.18698056, -0.12247711, 1.01875469, 0.62176455],
[ 0.88518599, 1.44812978, 0.18516454, -0.82940688],
[ 0.22833207, 2.16216305, -1.05428154, -0.71741654],
[ 2.15067166, -2.10548264, 0.44120789, 0.1395501 ]])
names!='Bob'
Out[142]: array([False, True, True, False, True, True, True])
cond=names=='Bob'
data(~cond)
Traceback (most recent call last):
File "<ipython-input-144-cafb54a05406>", line 1, in <module>
data(~cond)
TypeError: 'numpy.ndarray' object is not callable
data[~cond]
Out[145]:
array([[ 0.57533365, 1.69365588, -1.05694541, -0.41405561],
[-0.18698056, -0.12247711, 1.01875469, 0.62176455],
[ 0.88518599, 1.44812978, 0.18516454, -0.82940688],
[ 0.22833207, 2.16216305, -1.05428154, -0.71741654],
[ 2.15067166, -2.10548264, 0.44120789, 0.1395501 ]])
mask=(names=='Bob')|(names=='Will')
mask
Out[147]: array([ True, False, True, True, True, False, False])
data[mask]
Out[148]:
array([[ 1.66189273, -1.74527032, -0.14516128, 1.13129175],
[-0.18698056, -0.12247711, 1.01875469, 0.62176455],
[ 0.95455323, 1.76981728, -0.50373742, 1.24920993],
[ 0.88518599, 1.44812978, 0.18516454, -0.82940688]])
data[data<0]=0
data
Out[150]:
array([[1.66189273, 0. , 0. , 1.13129175],
[0.57533365, 1.69365588, 0. , 0. ],
[0. , 0. , 1.01875469, 0.62176455],
[0.95455323, 1.76981728, 0. , 1.24920993],
[0.88518599, 1.44812978, 0.18516454, 0. ],
[0.22833207, 2.16216305, 0. , 0. ],
[2.15067166, 0. , 0.44120789, 0.1395501 ]])
data[names!='Joe']=7
data
Out[152]:
array([[7. , 7. , 7. , 7. ],
[0.57533365, 1.69365588, 0. , 0. ],
[7. , 7. , 7. , 7. ],
[7. , 7. , 7. , 7. ],
[7. , 7. , 7. , 7. ],
[0.22833207, 2.16216305, 0. , 0. ],
[2.15067166, 0. , 0.44120789, 0.1395501 ]])
data
Out[165]:
array([[7. , 7. , 7. , 7. ],
[0.57533365, 1.69365588, 0. , 0. ],
[7. , 7. , 7. , 7. ],
[7. , 7. , 7. , 7. ],
[7. , 7. , 7. , 7. ],
[0.22833207, 2.16216305, 0. , 0. ],
[2.15067166, 0. , 0.44120789, 0.1395501 ]])
data[names=='Joe']
Out[166]:
array([[0.57533365, 1.69365588, 0. , 0. ],
[0.22833207, 2.16216305, 0. , 0. ],
[2.15067166, 0. , 0.44120789, 0.1395501 ]])
data[names=='Joe'][[True,False,True]]
Out[167]:
array([[0.57533365, 1.69365588, 0. , 0. ],
[2.15067166, 0. , 0.44120789, 0.1395501 ]])
总结:
1.布尔索引就是用True或False的列表对ndarray进行选择。是True就留下,False就不要。
data[names==‘Bob’]本质上是data**[[** True, False, False, True, False, False, False**]]**
注意:列表长度要与数组的最外轴(axis=0)的长度相同。
不等于 | != |
---|---|
等于 | == |
非 | ~ |
或 | | |
且 | & |
python中的关键字 and和or对布尔值数组没用,要用**&** 和**|**
不信试试看:
a=np.array([True,False,False,True,True])
b=np.array([True,True,False,False,True])
a&b
Out[176]: array([ True, False, False, False, True])
a and b
Traceback (most recent call last):
File "<ipython-input-177-61df3bd186ad>", line 1, in <module>
a and b
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
a|b
Out[179]: array([ True, True, False, True, True])
a or b
Traceback (most recent call last):
File "<ipython-input-180-51429399a6cf>", line 1, in <module>
a or b
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
a == b
Out[181]: array([ True, False, True, False, True])
神奇索引
用整数数组进行数据索引
arr=np.empty((8,4))
for i in range(8):
arr[i]=i
arr
Out[188]:
array([[0., 0., 0., 0.],
[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.],
[4., 4., 4., 4.],
[5., 5., 5., 5.],
[6., 6., 6., 6.],
[7., 7., 7., 7.]])
arr[[4,3,0,6]]
Out[189]:
array([[4., 4., 4., 4.],
[3., 3., 3., 3.],
[0., 0., 0., 0.],
[6., 6., 6., 6.]])
arr[[-3,-5,-7]]
Out[190]:
array([[5., 5., 5., 5.],
[3., 3., 3., 3.],
[1., 1., 1., 1.]])
arr=np.arange(32).reshape(8,4)
arr
Out[192]:
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],
[24, 25, 26, 27],
[28, 29, 30, 31]])
arr[[1,5,7,2],[0,3,1,2]]
Out[193]: array([ 4, 23, 29, 10])
#这里取得是元素(1,0),(5,3),(7,1),(2,2)
arr[[1,5,7,2]][:,[0,3,1,2]]
Out[194]:
array([[ 4, 7, 5, 6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])
'''
arr[[1,5,7,2]]得到的结果是:
array([[ 4, 5, 6, 7],
[20, 21, 22, 23],
[28, 29, 30, 31],
[ 8, 9, 10, 11]])
在其结果上利用神奇数组:
arr[[1,5,7,2]][:,[0,3,1,2]]
表示:所有行(axis=0)的[0,3,1,2]列
取出来并按照这个顺序排列
'''
#验证下
a=arr[[1,5,7,2]]
a
Out[199]:
array([[ 4, 5, 6, 7],
[20, 21, 22, 23],
[28, 29, 30, 31],
[ 8, 9, 10, 11]])
a[:,[0,3,1,2]]
Out[200]:
array([[ 4, 7, 5, 6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])
总结:
1.神奇索引就是用索引的列表(如[1,2,3])代替基本切片中的连续切片([1:4])
2**.需要注意的是:**当行和列都是神奇索引时,行和列是一一对应的,这点与基本切片不同
3.神奇索引与切片不同,总是将数据复制到一个新的数组中
[201]: arr
Out[201]:
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],
[24, 25, 26, 27],
[28, 29, 30, 31]])
arr[[1,2,3],[1,2,3]]
Out[202]: array([ 5, 10, 15])
arr[1:4,1:4]
Out[203]:
array([[ 5, 6, 7],
[ 9, 10, 11],
[13, 14, 15]])
数组转置和换轴
用T属性转置
np.dot(arr1,arr2)实现内积
arr=np.arange(15).reshape((3,5))
arr
Out[207]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
arr.T
Out[208]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
arr
Out[209]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
用transpose()方法按编号置换轴
arr.swapaxes(1,2)也是重组数据,返回的是数据的视图,没有对数据进行复制
arr=np.random.randn(6,3)
arr
Out[211]:
array([[-1.45299078, 0.59732807, -0.14250867],
[ 0.16336516, -0.65935845, 0.30694993],
[-1.84957879, 0.30628195, -0.66442141],
[-0.31776909, 0.7678612 , 2.22656997],
[-0.40137935, 0.640686 , -0.4442813 ],
[ 1.39921238, 0.97795115, -1.72921245]])
np.dot(arr.T,arr)
Out[212]:
array([[ 7.77868995, -0.67492032, -1.46263678],
[-0.67492032, 2.84184084, -0.75704815],
[-1.46263678, -0.75704815, 8.70115817]])
arr=np.arange(16).reshape((2,2,4))
arr
Out[214]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
arr.transpose((1,0,2))
Out[215]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
arr
Out[216]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
arr.swapaxes(1,2)
Out[217]:
array([[[ 0, 4],
[ 1, 5],
[ 2, 6],
[ 3, 7]],
[[ 8, 12],
[ 9, 13],
[10, 14],
[11, 15]]])
通用函数
通用函数的特点:在ndarray数组中逐元素操作
一元通用函数举例:
arr=np.arange(10)
arr
Out[223]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.sqrt(arr)
Out[224]:
array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
np.exp(arr)
Out[225]:
array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
2.98095799e+03, 8.10308393e+03])
二元通用函数:接收两个数组,返回一个数组
x=np.random.randn(8)
y=np.random.randn(8)
x
Out[228]:
array([ 0.02041998, 0.54429125, -1.01677134, 0.71831296, -0.42047901,
0.15708647, 1.10203177, -1.51652284])
y
Out[229]:
array([-0.27234892, 0.23224975, 0.70161308, -0.95807876, 0.04557067,
0.40722427, -1.88295484, 0.04528729])
np.maximum(x,y)
Out[230]:
array([0.02041998, 0.54429125, 0.70161308, 0.71831296, 0.04557067,
0.40722427, 1.10203177, 0.04528729])
也有一些通用函数是返回多个数组的。如modf函数
arr=np.random.randn(7)*5
arr
Out[232]:
array([-6.3607882 , -4.22382782, -1.91776271, 0.39395429, -1.03049123,
-1.96652887, 1.53487404])
remainder,whole_part=np.modf(arr)
#小数部分
remainder
Out[234]:
array([-0.3607882 , -0.22382782, -0.91776271, 0.39395429, -0.03049123,
-0.96652887, 0.53487404])
#整数部分
whole_part
Out[235]: array([-6., -4., -1., 0., -1., -1., 1.])
常用一元通用函数
函数名 | 描述 |
---|---|
abs,fabs | 逐元素计算整数、浮点数或复数的绝对值 |
sqrt | 计算每个元素的平方根 相当于arr**0.5 |
square | 计算每个元素的平方 相当于arr**2 |
exp | 计算每个元素的自然指数值e**x |
log,log10,log2,log1p | 分别对应:自然对数(e为底),对数10为底,对数2为底,log(1+x) |
sign | 计算每个函数的符号值。正数返回1,负数返回-1,0返回0 |
ceil | 每个元素最高整数值。计算大于等于给定元素的最小整数 |
floor | 每个元素最小整数值。计算小于等于给定元素的最大整数 |
rint | 将元素保留到整数位,并保持dtype |
modf | 分别将数组的小数部分和整数部分按数组形式返回 |
isnan | 判断数组中的元素是否是一个NaN(非数值),返回布尔值数组 |
isfinite,isinf | 判断数组中元素是否有限(非inf 非Nan)返回布尔值数组。isfinite判断是否有限。isinf判断是否无限 |
cos,cosh,sin,sinh,tan,tanh | 常规的双曲三角函数 |
arccos,arccosh,arcsin | 反三角函数 |
arcsinh,arctan,arctanh | 反三角函数 |
logical_not | 对数组元素按位取反 |
常用二元通用函数
函数名 | 描述 |
---|---|
add | 数组的对应元素相加 |
subtract | 第一个数组对应元素减第二个数组对应元素 |
multiply | 数组的对应元素相乘 |
divide,floor_divide | 数组的对应元素除或整除 |
power | 第二个数组的元素作为第一个数组对应元素的幂次方 |
maximun,fmax | 逐元素计算最大值,fmax忽略NaN |
minimun,fmin | 逐元素计算最小值,fmin忽略NaN |
mod | 暗元素的求模计算(求除法的余数) |
copysign | 将第一个数组的符号值改为第二个数组的符号值 |
greater,greater_equal,less, less_equal,equal,not_equal | 进行逐元素的比较,返回布尔值数组,与数学中的>,>=,<,<=,==,!=效果一致 |
logical_and,logica_or,logical_xor | 进行逐个元素的逻辑操作(与& | ^效果一致) |
利用数组进行面向数组编程
这一块讲了meshgrid函数,和aqrt(x * *2+y * * 2)这个例子,我没看懂。。。
将条件逻辑作为数组操作
numpy.where函数是x if condition else y 的向量化版本
xarr=np.array([1.1,1.2,1.3,1.4,1.5])
yarr=np.array([2.1,2.2,2.3,2.4,2.5])
cond=np.array([True,False,True,True,False])
#直接用np.where的方法
result=np.where(cond,xarr,yarr)
result
Out[275]: array([1.1, 2.2, 1.3, 1.4, 2.5])
#比较麻烦的方法
result= [(x if c else y) for x,y,c in zip(xarr,yarr,cond)]
result
Out[278]: [1.1, 2.2, 1.3, 1.4, 2.5]
numpy.where(cond,x,y)的第二个和第三个参数可以都是标量
arr=np.random.randn(4,4)
arr
Out[280]:
array([[ 0.85696626, -1.60857253, 1.31861284, -0.82719154],
[ 0.10412124, -0.82471068, -0.02756983, -1.49950033],
[ 0.8394496 , 0.46467431, 0.058242 , 1.5018778 ],
[-0.4376989 , -3.00940137, -0.71733889, 1.01334973]])
np.where(arr>0,2,-2)
Out[281]:
array([[ 2, -2, 2, -2],
[ 2, -2, -2, -2],
[ 2, 2, 2, 2],
[-2, -2, -2, 2]])
数学和统计方法
基础数组统计方法
方法 | 描述 |
---|---|
sum | 沿着轴向计算所有元素的累和 |
mean | 数学平均,0长度的数组平均值为NaN |
std,var | 标准差和方差,可以选择自由度调整 |
min,max | 最大值和最小值 |
argmax,argmin | 最大值和最小值的位置 |
cumsum | 从0开始元素累积和 |
cumprod | 从1开始元素累积积 |
arr=np.random.randn(5,4)
arr
Out[283]:
array([[ 0.49327655, -2.01713663, 0.19575224, 0.29555457],
[ 0.5514309 , -1.24349369, 0.07392705, -0.90014341],
[ 1.17767081, -1.78974343, 1.23346216, 0.2064801 ],
[-0.14810732, 1.63192772, -0.75562869, 0.98942985],
[-0.26777346, -0.20647022, 0.80330759, 2.01532279]])
arr.mean()
Out[284]: 0.11695227376928281
np.mean(arr)
Out[285]: 0.11695227376928281
arr.sum()
Out[286]: 2.339045475385656
arr.mean(axis=1)
Out[287]: array([-0.25813832, -0.37956979, 0.20696741, 0.42940539, 0.58609668])
arr.sum(axis=0)
Out[288]: array([ 1.80649747, -3.62491625, 1.55082036, 2.60664389])
arr=np.arange(7)
arr
Out[291]: array([0, 1, 2, 3, 4, 5, 6])
arr.cumsum()
Out[292]: array([ 0, 1, 3, 6, 10, 15, 21])
arr=np.arange(9).reshape((3,3))
arr
Out[294]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
arr.cumsum(axis=0)
Out[295]:
array([[ 0, 1, 2],
[ 3, 5, 7],
[ 9, 12, 15]])
arr.cumprod(axis=1)
Out[296]:
array([[ 0, 0, 0],
[ 3, 12, 60],
[ 6, 42, 336]])
1.axis=0表示计算每一列的统计值
axis=1表示计算每一行的统计值
2.cumsum\cumprod累计函数不会聚合,会产生中间结果
布尔值数组的方法
前面的函数作用于布尔值数组时,True强制为1,False强制为0
arr=np.random.randn(100)
(arr>0).sum()
Out[298]: 48
bools=np.array([False,True,False,False])
bools.any()
Out[300]: True
bools.all()
Out[301]: False
any()判断布尔值数组是否至少有一个True
all()判断布尔值数组是否全是True
排序
arr=np.random.randn(6)
arr
Out[303]:
array([-0.02104488, -0.55664439, 2.05569151, -0.91685783, 1.46872205,
0.59973902])
arr.sort()
arr
Out[305]:
array([-0.91685783, -0.55664439, -0.02104488, 0.59973902, 1.46872205,
2.05569151])
arr=np.random.randn(5,3)
arr
Out[307]:
array([[ 0.8333146 , -0.97120399, 0.84619803],
[-1.70574943, 1.30235056, 0.89352448],
[-1.62403652, 1.31006341, 0.66657965],
[-1.58609841, 1.3803932 , -1.34666979],
[-1.20685289, 1.45930659, 0.13439744]])
arr.sort(1)
#表示对每一行进行排序
arr
Out[309]:
array([[-0.97120399, 0.8333146 , 0.84619803],
[-1.70574943, 0.89352448, 1.30235056],
[-1.62403652, 0.66657965, 1.31006341],
[-1.58609841, -1.34666979, 1.3803932 ],
[-1.20685289, 0.13439744, 1.45930659]])
arr.sort()方法是对原数组进行排序
np.sort()方法返回的是已经排序好的数组拷贝
唯一值与其他集合逻辑
names=np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
np.unique(names)
Out[311]: array(['Bob', 'Joe', 'Will'], dtype='<U4')
ints=np.array([3,3,3,2,2,1,1,4,4])
np.unique(ints)
Out[313]: array([1, 2, 3, 4])
# 纯python的方法
sorted(set(names))
Out[315]: ['Bob', 'Joe', 'Will']
values=np.array([6,0,0,3,2,5,6])
np.in1d(values,[2,3,6])
Out[317]: array([ True, False, False, True, True, False, True])
数组的集合操作
方法 | 描述 |
---|---|
unique(x) | 计算x的唯一值,并排序 |
intersect1d(x,y) | 计算x和y的交集,并排序 |
union1d(x,y) | 计算x和y的并集,并排序 |
in1d(x,y) | 计算x中的元素是否在y中,返回一个布尔值数组 |
setdiff1d(x,y) | 差集,计算在x中但不在y中的元素 |
setxor1d(x,y) | 异或集,在x或y中,但不同时在x和y中的元素 |
示例:
x=np.arange(10)
x
Out[319]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y=np.arange(5,12)
y
Out[321]: array([ 5, 6, 7, 8, 9, 10, 11])
np.intersect1d(x,y)
Out[322]: array([5, 6, 7, 8, 9])
np.union1d(x,y)
Out[323]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
np.in1d(x,y)
Out[324]:
array([False, False, False, False, False, True, True, True, True,
True])
np.setdiff1d(x,y)
Out[325]: array([0, 1, 2, 3, 4])
np.setxor1d(x,y)
Out[326]: array([ 0, 1, 2, 3, 4, 10, 11])
使用数组进行文件输入和输出
(了解即可)
1.np.save()和np.load()
np.savez()用于在未压缩文件中保存多个数组。将数组作为参数传递给该函数。
2.默认情况下,数组是以未压缩的格式进行存储的,后缀名是.npy
arr=np.arange(10)
np.save('some_array',arr)
np.load('some_array.npy')
Out[329]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.savez('array_archive.npz',a=arr,b=arr)
arch=np.load('array_archive.npz')
#获得的是一个字典对象
arch['a']
Out[332]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arch['b']
Out[333]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.savez_compressed('arrays_compresses.npz',a=arr,b=arr)
#将数组存入已经压缩的文件
线性代数
-
Numpy中*是矩阵的 逐元素乘积,而不是矩阵的逐元素点乘积。Numpy中的dot()函数用于点积
x=np.array([[1.,2.,3.],[4.,5.,6.]]) y=np.array([[6.,23.],[-1,7],[8,9]]) x Out[338]: array([[1., 2., 3.], [4., 5., 6.]]) y Out[339]: array([[ 6., 23.], [-1., 7.], [ 8., 9.]]) x.dot(y) Out[340]: array([[ 28., 64.], [ 67., 181.]]) np.dot(x,y) Out[341]: array([[ 28., 64.], [ 67., 181.]]) np.dot(x,np.ones(3)) #二维数组和一个适当的一维数组;2*3 与 3个元素的一维数组可以点积(自动转换 的感觉) Out[342]: array([ 6., 15.]) #@作为中缀操作符,也用于点乘积操作 #(中缀操作符就是类似于1+2中的“+”放在中间的这种操作符) x@np.ones(3) Out[343]: array([ 6., 15.])
numpy.linalg拥有一个矩阵分解的标准函数集以及其他常用函数
(这部分。。代数我忘得差不多了,没有怎么理解,就先做了解,需要用的时候再深入学些)
from numpy.linalg import inv,qr
#inv()计算矩阵的逆矩阵
#qr计算QR分解
X=np.random.randn(5,5)
mat=X.T.dot(X)
#计算X的转置与X的点乘积
inv(mat)#计算逆矩阵
Out[349]:
array([[ 209.79002291, 80.09896573, -381.7770312 , 110.49588295,
50.17860874],
[ 80.09896573, 30.8323335 , -146.03696956, 42.22880307,
19.54024932],
[-381.7770312 , -146.03696956, 696.94349878, -201.45062469,
-92.1292433 ],
[ 110.49588295, 42.22880307, -201.45062469, 58.49883003,
26.85459821],
[ 50.17860874, 19.54024932, -92.1292433 , 26.85459821,
13.93537618]])
mat.dot(inv(mat))#矩阵与逆矩阵的点乘积
Out[350]:
array([[ 1.00000000e+00, 8.41705404e-15, 3.42951772e-15,
1.34049441e-14, 2.43463661e-14],
[ 1.24809524e-14, 1.00000000e+00, -2.11322476e-13,
3.22323350e-14, 2.25430697e-14],
[-1.05486516e-16, -5.70583392e-15, 1.00000000e+00,
-5.52686487e-16, 1.14883122e-15],
[-6.92612402e-14, -1.82836762e-14, -2.77147389e-13,
1.00000000e+00, 1.59605169e-14],
[-2.74305169e-15, -1.42239067e-14, 2.67353054e-14,
3.60674648e-16, 1.00000000e+00]])
q,r=qr(mat)# QR分解
r
Out[352]:
array([[-4.26101532, 5.82643495, 0.19916687, 5.61378591, -2.34532889],
[ 0. , -4.4611308 , -0.75149875, 0.39079013, 0.53538998],
[ 0. , 0. , -1.0229964 , -3.72485841, 0.41074371],
[ 0. , 0. , 0. , -0.26805248, 0.58553327],
[ 0. , 0. , 0. , 0. , 0.00901564]])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NoxXqoSx-1651126706532)(C:\Users\章ky\AppData\Roaming\Typora\typora-user-images\image-20220419200640380.png)]
伪随机数生成
numpy.random中的部分函数列表
函数 | 描述 |
---|---|
seed | 向随机数生成器传递随机状态种子 |
permutation | 返回一个序列的随机排序,或者返回一个乱序的整数范围排序 |
shuffle | 随机排序一个序列 |
rand | 从均匀分布中抽取样本 |
randint | 根据所给定的由低到高的范围抽取随机整数 |
randn | 从均值0方差1的正态分布中抽取样本 |
binomial | 从二项分布中抽取样本 |
normal | 从正态(高斯)分布中抽取样本 |
beta | 从beta分布中抽取样本 |
chisquare | 从卡方分布中抽取样本 |
gamma | 从伽马分布中抽取样本 |
uniform | 从均匀[0,1)分布中抽取样本 |
samples=np.random.normal(size=(4,4))
#获得一个4*4的正态分布样本
samples
Out[355]:
array([[ 0.92599667, 0.60227413, 0.42960072, 1.69126364],
[ 1.11713741, 0.7871298 , 1.0569868 , 1.68851797],
[-0.95893428, 0.45718241, 0.26019146, -0.38231113],
[-0.71246899, 0.48054694, -1.67207602, 0.11021214]])
#对比numpy的高效
from random import normalvariate
N=1000000
%timeit samples =[normalvariate(0,1)for _ in range(N) ]
838 ms ± 20.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.random.normal(size=N)
26.3 ms ± 602 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
----------- | ------------------------------------------------------ |
| seed | 向随机数生成器传递随机状态种子 |
| permutation | 返回一个序列的随机排序,或者返回一个乱序的整数范围排序 |
| shuffle | 随机排序一个序列 |
| rand | 从均匀分布中抽取样本 |
| randint | 根据所给定的由低到高的范围抽取随机整数 |
| randn | 从均值0方差1的正态分布中抽取样本 |
| binomial | 从二项分布中抽取样本 |
| normal | 从正态(高斯)分布中抽取样本 |
| beta | 从beta分布中抽取样本 |
| chisquare | 从卡方分布中抽取样本 |
| gamma | 从伽马分布中抽取样本 |
| uniform | 从均匀[0,1)分布中抽取样本 |
samples=np.random.normal(size=(4,4))
#获得一个4*4的正态分布样本
samples
Out[355]:
array([[ 0.92599667, 0.60227413, 0.42960072, 1.69126364],
[ 1.11713741, 0.7871298 , 1.0569868 , 1.68851797],
[-0.95893428, 0.45718241, 0.26019146, -0.38231113],
[-0.71246899, 0.48054694, -1.67207602, 0.11021214]])
#对比numpy的高效
from random import normalvariate
N=1000000
%timeit samples =[normalvariate(0,1)for _ in range(N) ]
838 ms ± 20.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.random.normal(size=N)
26.3 ms ± 602 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)