zoukankan      html  css  js  c++  java
  • numpy

    什么是numpy

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

    numpy创建数组(矩阵)

    创建数组:

    import numpy as np
    a = np.array([1, 2, 3, 4, 5])
    b = np.array(range(1, 6))
    c = np.arange(1, 6)
    # 上面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
    

    数据的类型

    In [3]: a.dtype
    Out[3]: dtype('int64')
    

    数据类型的操作

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

    In [11]: a = np.array([1, 0, 1, 0], dtype=np.bool)  # 或者使用dtype='?'
    In [12]: a
    Out[12]: array([ True, False,  True, False])
    

    修改数组的数据类型:

    In [13]: a.astype('i2')  # 或者使用a.astype(np.int16)
    Out[13]: array([1, 0, 1, 0], dtype=int16)
    

    修改浮点型的小数位数:

    In [30]: b
    Out[30]:
    array([0.07996214, 0.89966202, 0.27985576, 0.84551686, 0.77378861,
           0.69867185, 0.83677068, 0.30732802, 0.84521435, 0.88867764])
    
    In [31]: np.round(b, 2)
    Out[31]: array([0.08, 0.9 , 0.28, 0.85, 0.77, 0.7 , 0.84, 0.31, 0.85, 0.89])
    

    数组的形状

    b = a.reshape(3, 4)
    
    In [36]: b
    Out[36]:
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    
    In [37]: b.shape
    Out[37]: (3, 4)
    

    把数据转化为1维度数据

    In [38]: b.reshape(1, 12)
    Out[38]: array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]])
    # 这是一维数组么?
    
    In [39]: b.flatten()
    Out[39]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
    

    数组和数的计算

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

    加法减法

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

    乘法除法

    In [45]: a *3
    Out[45]:
    array([[ 3,  6,  9, 12, 15],
           [18, 21, 24, 27, 30]])
    

    这是一个numpy的广播机制造成的,在运算过程中,加减乘除的值被广播到所有的元素上面

    不同维度的数组计算

    In [46]: a
    Out[46]:
    array([[ 1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10]])
    
    In [47]: c = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
    
    In [48]: a * c
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-48-3f6f667472ca> in <module>()
    ----> 1 a * c
    
    ValueError: operands could not be broadcast together with shapes (2,5) (3,4)
    

    广播原则

    如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。

    轴(axis)

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

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

    numpy读取数据

    CSV:Comma-Separated Value,逗号分隔值文件
    显示:表格状态
    源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录
    由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,为了方便教学,我们会经常操作csv格式的文件,但是操作数据库中的数据也是很容易实现的

    np.loadtxt(frame, dtype=np.float, delimiter=None, skiprows=0, usecols=None, unpack=False)
    
    参数 解释
    frame 文件、字符串或产生器,可以是.gz或bz2压缩文件
    dtype 数据类型,可选,csv的字符串以什么数据类型读入数组中,默认np.float
    delimiter 分隔字符串,默认是任何空格,改为 逗号
    skiprows 跳过前x行,一般跳过第一行表头
    usecols 读取指定的列,索引,元组类型
    unpack 如果True,读入属性将分别写入不同数组变量,False读入数据只写入一个数组变量,默认False

    numpy中的转置

    转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据

    In [102]: t = np.array([[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11], [12, 13, 14, 15,16, 17]])
    
    In [103]: t.transpose()
    Out[103]:
    array([[ 0,  6, 12],
           [ 1,  7, 13],
           [ 2,  8, 14],
           [ 3,  9, 15],
           [ 4, 10, 16],
           [ 5, 11, 17]])
    
    In [104]: t.swapaxes(1, 0)
    Out[104]:
    array([[ 0,  6, 12],
           [ 1,  7, 13],
           [ 2,  8, 14],
           [ 3,  9, 15],
           [ 4, 10, 16],
           [ 5, 11, 17]])
    
    In [105]: t.T
    Out[105]:
    array([[ 0,  6, 12],
           [ 1,  7, 13],
           [ 2,  8, 14],
           [ 3,  9, 15],
           [ 4, 10, 16],
           [ 5, 11, 17]])
    

    以上的三种方法都可以实现二维数组的转置的效果,大家能够看出来,转置和交换轴的效果一样

    numpy索引和切片

    对于刚刚加载出来的数据,我如果只想选择其中的某一列(行)我们应该怎么做呢?
    其实操作很简单,和python中列表的操作一样

    In [118]: a
    Out[118]:
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    
    In [119]: a[1]  # 取一行
    Out[119]: array([4, 5, 6, 7])
    
    In [120]: a[:,2]  # 取一列
    Out[120]: array([ 2,  6, 10])
    
    In [121]: a[1:3]  # 取多行
    Out[121]:
    array([[ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    
    In [122]: a[:,2:4]  # 取多列
    Out[122]:
    array([[ 2,  3],
           [ 6,  7],
           [10, 11]])
           
    In [128]: a[[0, 2],[0, 3]]  # 取多个不相邻的点
    Out[128]: array([ 0, 11])
    

    numpy中数值的修改

    In [132]: t
    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]])
    
    In [133]: t[:, 2:4]
    Out[133]:
    array([[ 2,  3],
           [ 8,  9],
           [14, 15],
           [20, 21]])
    
    In [134]: t[:, 2:4] = 0
    
    In [135]: t
    Out[135]:
    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]])
    

    numpy中布尔索引

    In [142]: t
    Out[142]:
    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 [143]: t<10
    Out[143]:
    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]])
    
    In [144]: t[t<10]
    Out[144]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [145]: t
    Out[145]:
    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 [146]: t[t<10] = 0
    
    In [147]: t
    Out[147]:
    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]])
    

    numpy中三元运算符

    In [149]: t
    Out[149]:
    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]])
    
    In [150]: t = np.arange(24).reshape((4, 6))
    
    In [151]: t
    Out[151]:
    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 [152]: np.where(t<10,0,10)
    Out[152]:
    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]])
    

    numpy中的clip(裁剪)

    In [166]: t
    Out[166]:
    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]], dtype=float32)
    
    In [167]: t.clip(10, 18)
    Out[167]:
    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]], dtype=float32)
    

    小于10的替换为10,大于18的替换为了18,但是nan没有被替换

    数组的拼接

    In [169]: t1 = np.arange(12).reshape(2, 6)
    
    In [170]: t1
    Out[170]:
    array([[ 0,  1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10, 11]])
    
    In [171]: t2 = np.arange(12, 24).reshape(2, 6)
    
    In [172]: t2
    Out[172]:
    array([[12, 13, 14, 15, 16, 17],
           [18, 19, 20, 21, 22, 23]])
    
    In [173]: np.vstack((t1, t2))  # 竖直拼接(vertically)
    Out[173]:
    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 [174]: np.hstack((t1, t2))  # 水平拼接(horizontally)
    Out[174]:
    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 [216]: t1
    Out[216]:
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    
    In [217]: t1[[1, 2], :] = t1[[2, 1], :]
    
    In [218]: t1
    Out[218]:
    array([[ 0,  1,  2,  3],
           [ 8,  9, 10, 11],
           [ 4,  5,  6,  7]])
    
    In [219]: t1[:, [0, 2]] = t1[:, [2, 0]]
    
    In [220]: t1
    Out[220]:
    array([[ 2,  1,  0,  3],
           [10,  9,  8, 11],
           [ 6,  5,  4,  7]])
    

    numpy中的nan和inf

    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)

    numpy中的nan的注意点

    1. 两个nan是不相等的
    In [27]: np.nan == np.nan
    Out[27]: False
    
    1. np.nan != np.nan
    In [34]: np.nan != np.nan
    Out[34]: True
    
    1. 利用以上的特性,判断数组中nan的个数
    In [38]: t
    Out[38]: array([ 1.,  2., nan])
    
    In [39]: np.count_nonzero(t!=t)
    Out[39]: 1
    
    1. 由于2,那么如何判断一个数字是否为nan呢?通过np.isnan(a)来判断,返回bool类型比如希望把nan替换为0
    In [40]: t
    Out[40]: array([ 1.,  2., nan])
    
    In [41]: np.isnan(t)
    Out[41]: array([False, False,  True])
    
    1. nan和任何值计算都为nan

    那么问题来了,在一组数据中单纯的把nan替换为0,合适么?会带来什么样的影响?

    比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者直接删除有缺失值的一行

    numpy中常用的统计函数

    求和:t.sum(axis=None)
    均值:t.mean(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则返回一个当前轴上的结果

    numpy更多好用的方法

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

    numpy生产随机数

    参数 解释
    .rand(d0, d1, ..dn) 创建d0-dn维度的均匀分布的随机数数组,浮点数,范围从0-1
    .randn(d0, d1, ..dn) 创建d0-dn维度的正态分布的随机数数组,浮点数,平均数0,标准差1
    .randint(low, high, (shape)) 从给定上下限范围选取随机数整数,范围是low,high, 形状是shape
    uniform(low, high, (size)) 产生具有均匀分布的数组,low为起始值,high结束值,size形状
    .normal(loc, scale, (size)) 从指定正态分布中随机抽取样本,分布中心是loc(概率分布的均值),标准差是scale,形状是size
    seed(s) 随机数种子,s是给定的种子值。因为计算机生成的是伪随机数,所以通过设定相同的随机数种子,可以生成相同的随机数

    numpy的注意点copy和view

    1. a = b 完全不复制,a和b相互影响
    2. a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,它们两个完全的数据变化是一致的,
    3. a = b.copy(),复制,a和b互不影响
  • 相关阅读:
    python setup.py install 失败
    Python xlsx 读取
    Java ArrayList Sort
    java console ( mac osx ) 命令行编码
    Lucene Query Term Weighting
    Fast Intro To Java Programming (2)
    随感 20150512
    循环数组中找查找某个数值
    数字内组合得到下一个比该数大的数
    android activity空指针异常解决问题解决
  • 原文地址:https://www.cnblogs.com/colden/p/9885416.html
Copyright © 2011-2022 走看看