啃书《利用python进行数据分析》NumPy部分

啃书《利用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有很多,在转换时也可以用类型代码表示

image-20220419145710308

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)
#将数组存入已经压缩的文件

线性代数

  1. 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)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值