numpy

一、什么是numpy

  一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算

二、numpy创建数组(矩阵)

创建数组

        import numpy as np

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

        b = np.array(range(1,6))    // 也可以写成取步长 b = np.array(range(1,6,2) 步长为2

        c = np.arange(1,6)// c = np.arange(1,6,2)

                上面a,b,c内容是相同的,创建结果是一样的,注意区分arange 和range 的区别

        np.arange的用法:arange([start,] stop[, step,],dtype = None)

数组的类名:

In [1] : a = np.array([1,2,3,4,5])

In [2] : type(a)

Out[2] : numpy.ndarray  // ndarray 是numpy 中的一种数据类型

数据的类型

In [3] : a.dtype // dtype 为当前array中元素的类型

Out [3] :dtype('int64') // int64为元素的类型

numpy 中常见的更多数据类型

int8 , uint8 ,int16 ,uint16 , int32 ,uint32 , int64 , uint64 , float16 , float32 , float64 ,float 128 ,complex64 ,complex128 ,bool

类型代码 // 与上面对应  

i1 ,u1,i2 ,u2,i4 , u4 ,i8 ,u8 ,f2 , f4或f , f8或d , f16或 g ,c8 , c16 , c32 


三、数据类型的操作

指定创建的数组的数据类型

In [40] : a = np.array([1,0,1,0],dtype = np.bool) # 或者使用dtype = '?'

In [41] :a

Out [41] : array([ Ture , False , True ,False], dtype= bool)

修改数据的数据类型:

In [44] : a.astype("i1") # 或者使用a.astype(np.int8)

Out[44] : array([1, 0, 1, 0], dtype =int8)

修改浮点型的小数位数:

In [53]:b

Out[53]:
array([ 0.0485436,0.26320629,0.69646413,0.71811003,0.3576838 ,
0.58919477,0.84757749,0.52428633,0.486302,0.48908838])
In [54]: np.round(b,2) # round 第二个参数为保留小数的位数
0ut[54]: array([ 0.05,0.26,0.7 ,0.72,0.36,0.59,0.85,0.52, 0.49])

四、数组的形状

In [60]: a = np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])

In [61]: a

Out[61]:
array([[3,4,5,6,7,8],
[4,5,6,7,8,9]])


查看数组的形状:
In [62]: a.shape

Out[62]:(2,6)


修改数组的形状:
In [63]: a.reshape((3,4)) # reshape() 改变原来的形状的函数

Out[63]:
array([[3,4,5,6,
[7,8,4,5],[6,7,8,9]])


In [64]: a.shape()
Out[64]:(2,6) 一>为什么a还是2行6列的数组呢? # 因为操作并未改变a的本身,原地操作

输出的元组有几个数字即为几维 #一维为(n,) 有一个逗号隔开

#若输出为(x , y ,z ) 即为三维,x 可看成块 ,y 可看成行 ,z 可看成列

In [65]: b = a.reshape(3,4)
In [66]: b.shape

Out[66]: (3,4)
In [67]:b

Out[67]:
array([[3,4,5,6],
[7,8,4,5],[6,7,8,9]])


把数组转化为1维度数据
In [69]: b.reshape(1,12)
0ut[69]: array([[3,4,5,6,7,8,4,5,6,7,8,9]])
一>这是一维数组么? #显然不是一维数组,这是一个二位数组,因为reshape 参数有两个数字


In [70]: b.flatten() # flatten() 是可以直接转化为一维的数组
0ut[70]: array([3,4,5,6,7,8,4,5,6,7,8,9])

五、数组和数的计算

In [71]:a

Out[71]:
array([[3,4,5,6,7,8],
[4,5,6,7,8,9]])


加法减法
In [72]: a+1

Out[72]:
array([[ 4, 5, 6, 7, 8, 9],
[5, 6, 7, 8,9,10]])


乘法除法
In [73]: a*3

Out[73]:
array([[ 9,12,15,18,21,24],
[12,15,18,21,24,27]])
有趣吧,这是一个numpy的广播机制造成的,在运算过程中,加减乘除的值被广播到所有的元素上面

In [78]: a

Out[78]:
array([[3,4,5,6,7,8],
[4,5,6,7,8,9]])
In [79]:b

Out[79]:
array([[21,22,23,24,25,26],
[27,28,29,30,31,32]])


数组和数组的加减法

In [80]: a+b

Out[80]:
array([[24,26,28,30,32,34],
[31,33,35,37,39,41]])


数组和数组的乘除法

In [81]: a*b

Out[81]:
array([[ 63,88,115,144,175,208],
[108,140,174,210,248,288]])

In [86]: c

Out[86]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7,8],[ 9,10,11,12]])
In [87]: a

Out[87]:
array([[3,4,5,6,7,8],
[4,5,6,7,8,9]])


#不同维度的数组计算 In [88]: a*c

ValueError: operands could not be broadcast together with shapes(2,6) (3,4)

注意:每个维度都不同的数组不能进行计算

In [92]:a #2行6列的数组                     In [94]:a-c 
0ut[92]:                                               Out[94]: 
array([[3,4,5,6,7,8],             array([[2,2,2,2,2,2], 
[4,5,6,7,8,9]])                         [3,3,3,3,3,3]]) 
In [93]:c #1行6列的数组                     In [95]: a*c 
0ut[93]: array([1,2,3,4,5,6])   Out[95]: 
                                                           array([[ 3,8,15,24,35,48],
                                                           [4,10,18,28,40,54]])

#行相同,列为1或行为1 ,列相同则数组可以计算

广播原则

如果两个数组的 后缘维度(trailing dimension,即从末尾开始算起的维度 的轴长 
度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
怎么理解呢?
可以把维度指的是shape所对应的数字个数

那么问题来了:
shape为(3,3,3)的数组能够和(3,2)的数组进行计算么?#这个显然不可以

shape为(3,3,2)的数组能够和(3,2)的数组进行计算么?#这个是可以的,可以分块计算

有什么好处呢?
举个例子:每列的数据减去列的平均值的结果

六、轴(axis)

在numpy中可以理解为方向,使用0,1,2...数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2,3)),有0,1,2轴

#0轴为行,1轴为列,2轴为‘块’

有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值

那么问题来了:
在前面的知识,轴在哪里?
回顾np.arange(0,10).reshape((2,5)),reshpe中2表示0轴长度(包含数据的条数)为2,1轴长度为5,2X5一共10个数据

七、numpy读取数据

CSV:Comma-Separated Value,逗号分隔值文件显示:表格状态
源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录
由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据

np.loadtxt(frame,dtype=np.float,delimiter= None,skiprows=0,usecols= None,uppack=False)

frame 是文件地址,unpack效果为转置,即行列转换

np.loadtxt(US_video_data_numbers_path,delimiter=",",dtype=int,unpack=1)
注意其中添加delimiter和dtype以及unpack的效果
delimiter :指定边界符号是什么,不指定会导致每行数据为一个整体的字符串而报错 dtype:默认情况下对于较大的数据会将其变为科学计数的方式

那么unpack的效果呢?
upack:默认是Flase(0),默认情况下,有多少条数据,就会有多少行
为True(1)的情况下,每一列的数据会组成一行,原始数据有多少列,加载出来的数据就会有多少行,相当于转置的效果


转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据
In [45]: t                                                                In [47]: t.swapaxes(1,0) 
0ut[45]:                                                                 0ut[47]: 
array([[ 0, 1,2,3,4,5],                             array([[ θ, 6,12], 
[6, 7, 8,9,10,11],                                              [1,7,13], 
[12,13,14,15,16,17]])                                         [ 2, 8,14], 
                                                                                        [ 3, 9,15],
In [46]:t.transpose()                                                        [4,10,16], 
0ut[46]: [ 5,11,17]]) 
array([[ 0, 6,12],                                           In [48]:t.T 
[1, 7,13],                                                      0ut[48]: 
[2, 8,14],                                                      array([[ θ, 6,12], 
[3, 9,15],                                                                 [ 1, 7,13], 
[4,10,16],                                                                [ 2, 8,14], 
[ 5,11,17]])                                                                 [ 3, 9,15], 
                                                                                       [ 4,10,16],                                               

                                                                                       [ 5,11,17]])
以上的三种方法都可以实现二维数组的转置的效果,能够看出来,转置和交换轴的效果一样

八、numpy索引和切片

对于刚刚加载出来的数据,我如果只想选择其中的某一列(行)我们应该怎么做呢?
其实操作很简单,和python中列表的操作一样
In [83]: a                                                         In [88]: a[1:3] #取多行 
Out[83]:                                                          Out[88]: 
array([[ 0, 1, 2,3]                                             array([[ 4, 5, 6, 7],

            [4 ,    5,   6 ,  7]                                                        [8,9,10,11]]) 
           [ 8, 9,10,11]])                                         


In [84]: a[1] #取一行                                        In [89]: a[:,2:4] #取多列 
Out[84]: array([4,5,6,7])                           0ut[89]: 
                                                                          array([[ 2, 3],
In [85]: a[:,2]#取一列                                                    [6, 7], 
Out[85]: array([ 2, 6,10])                                         [10,11])

取行  : t[2]

取连续多行  : t[2:]

取不连续多行  :  t[2,8,10]

取列  : t[1, :]                  t[2:, :]                t[[2,10,3],  : ]                 t[: ,0]

取连续的多列         t[: ,2:]

取不连续的多列      t[: ,[0,2]]

取行和列                  t[2,3]

取多行和多列           t[2:5,1:4]

取多个不相邻的点         t[[0,2,2],[0,1,3]]

九、numpy中数值的修改

In [4]:t

Out[4]:
array([[ θ, 1, 2, 3, 4,5],
          [6, 7, 8,9,10,11],

          [12,13,14,15,16,17],       

           [18,19,20,21,22,23]])


In [6]: t[:,2:4]

Out[6]:
array([[ 2, 3],
           [ 8, 9],

           [14,15],

           [20,21]])


In [7]: t[:,2:4] = 0

In [8]:t

Out[8]:
array([[ 0, 1, 0, 0, 4,5],
          [6, 7, 0,0,10,11],

          [12,13,0,0,16,17],

         [18,19, 0, 0,22,23]])

修改行列的值,我们能够很容易的实现,但是如果条件更复杂呢?
比如我们想要把t中小于10的数字替换为3

t[t<10] = 3

#t[t<10] 表示的是为True的位置即满足条件的  

十、numpy中布尔索引

In [14]:t = np.arange(24).reshape((4,6))

In [15]: t<10

Out[15]:
array([[ True, True, True, True, True, True],
          [ True, True, True, True, False, False],

          [False, False, False, False, False, False],
          [False, False, False, False, False, False]],dtype=bool)


In [16]: t[t<10]=0

In [17]: t
0ut[17]: array([[ 0, 0, 0, 0,0,0],

                       [ 0, 0, 0, 0,10,11],
                       [12,13,14,15,16,17],
                       [18,19,20,21,22,23]])

那么问题来了: 如果我们想把t中小于10的数字替换为0,把大 于10的替换为10,应该怎么做?

十一、numpy中三元运算符

In [19]:t = np.arange(24).reshape((4,6))

In [20]: t

Out[20]:
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]])


In [22]: np.where(t<10,0,10) #numpy的三元运算符  #意义为小于10的取0,其他取10

Out[22]:
array([[ 0,0,0, 0,0,0],

          [ 0, 0, 0,0,10,10],
          [10,10,10,10,10,10],
          [10,10,10,10,10,10]])

那么问题来了:如果我们想把t中小于10的数字替换为0,把大 于20的替换为20,应该怎么做?

十二、numpy中的clip(裁剪)

In [50]: t

Out[50]:
array([[0., 1., 2., 3., 4., 5.], 
           [6., 7., 8., 9., 10., 11.], 
           [12., 13., 14.,15., 16., 17.],
           [18., 19., 20., nan, nan,nan]])


In [52]: t.clip(10,18) #意思为将t里小于10的替换成10,大于18的替换为18

Out[52]:
array([[ 10.,10., 10., 10., 10.,10.],
           [10., 10., 10., 10., 10.,11.],

           [ 12., 13., 14., 15., 16., 17.],

           [ 18.,18., 18., nan, nan, nan]])

观察上面的操作: 
小于10的替换为10,大于18的替换为了18,但是nan没有被替换,那么nan是什么?

十三、numpy 中的nan 和inf

inf  ,nan为float类型

nan(NAN,Nan):not a number表示不是一个数字
什么时候numpy中会出现nan:
        当我们读取本地的文件为float的时候,如果有缺失,就会出现nan

        当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)


inf(-inf.inf):infinity,inf表示正无穷,-inf表示负无穷


什么时候回出现inf包括(-inf,+inf)
比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)

In [71]; a = np.inf


In [73]:type(a) 
Out[73]:float 


In [74]: a =np.nan

In [75]:type(a)

Out[75]:float

那么如何指定一个nan或者inf呢? 注意他们的type类型

numpy中nan的注意点

1.两个nan是不相等的                         In [76]: np.nan==np.nan 
                                                           0ut[76]: False


                                                                        In [81]: np.nan!=np.nan
2. np.nan!=np.nan                                           Out[81]:True 


                                                                        In [86]:t
3.利用以上的特性,判断数组中nan的个数     Out[86]: array([1., 2., nan]) 
                                                                        In [87]: np.count_nonzero(t!=t)

                                                                        Out[87]: 1

4.由于2,那么如何判断一个数字是否为nan呢?        In [89]: t
通过np.isnan(a) 来判断,返回bool类型                    Out[89]: array([ 1., 2., nan]) 
比如希望把nan替换为0

                                                                                  In [90]:t[np.isnan(t)]=0


5.nan和任何值计算都为nan                                      In [91]:t 
                                                                                  Out[91]: array([ 1., 2., 0.])

numpy中的nan的注意点

那么问题来了,在一组数据中单纯的把nan替换为0,合适么?会带来什么样的影响?
比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行

那么问题来了:
如何计算一组数据的中值或者是均值
如何删除有缺失数据的那一行(列)[在pandas中介绍]

十四、numpy中常用统计函数

求和:t.sum(axis=None)
均值:t.mean(a.axis=None)受离群点的影响较大

中值:np.median(t,axis=None)

最大值:t.max(axis=None)

最小值:t.min(axis=None)
极值:np.ptp(t,axis=None)即最大值和最小值只差
标准差:t.std(axis=None)


标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值反映出数据的波动稳定情况,越大表示波动越大,约不稳定

默认返回多维数组的全部的统计结果,如果指定axis则返回一个当前轴上的结果

十五、数组的拼接

In [164]:t1

Out[164]:
array([[ 0, 1,2,3, 4,5],
           [6, 7, 8,9,10,11]])
In [165]:t2

Out[165]:
array([[12,13,14,15,16,17],
           [18,19,20,21,22,23]])


In [166]: np.vstack((t1,t2))一>竖直拼接(vertically)

Out[166]:
array([[ θ, 1,2,3, 4, 5],
           [6, 7, 8,9,10,11],

           [12,13,14,15,16,17],

           [18,19,20,21,22,23]])
In [167]: np.hstack((t1,t2)) ->水平拼接(horizontally)

Out[167]:
array([[ 0, 1, 2, 3, 4,5,12,13,14,15,16,17],
           [6,7, 8,9,10,11,18,19,20,21,22,23]])

十六、数组的行列交换

In [180]:t = np.arange(12,24).reshape(3,4)

In [181]:t

Out[181]:
array([[13,13,14,15],
           [16,17,18,19],

           [20,21,22,23]])


In [182]:t[[1,2],:] = t[[2,1],:]#行交换


In [183]: t

Out[183]:
array([[12,13,14,15],
           [20,21,22,23],

           [16,17,18,19]])


In [184]: t[:,[0,2]] = t[:,[2,0]]#列交换


In [185]: t

Out[185]:
array([[14,13,12,15],
           [22,21,20,23],

           [18,17,16,19]])

十七、numpy更多好用的方法

1.获取最大值最小值的位置
        1. np.argmax(t.axis=0)
        2. np.argmin(t.axis=1) 
2.创建一个全0的数组:np.zeros((3,4))
3.创建一个全1的数组:np.ones((3,4))
4.创建一个对角线为1的正方形数组(方阵):np.eye(3)

numpy生成随机数

十八、numpy的注意点copy和view

1. a=b 完全不复制,a和b相互影响
2. a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的,
3. a = b.copy(),复制,a和b互不影响

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值