一、什么是Numpy
numpy官方文档:https://docs.scipy.org/doc/numpy/reference/?v=20190307135750html
NumPy是一个功能强大的Python库,主要用于对多维数组执行计算。NumPy这个词来源于两个单词-- Numerical和Python。 它是 Python 生态系统中数据分析、机器学习和科学计算的主力军。它极大地简化了向量和矩阵的操做处理。Python 数据科学相关的一些主要软件包(如 scikit-learn、SciPy、pandas 和 tensorflow)都以 NumPy 做为其架构的基础部分。除了能对数值数据进行切片(slice)和切块(dice)以外,使用 NumPy 还能为处理和调试上述库中的高级实例带来极大便利组。它将经常使用的数学函数都支持向量化运算,使得这些数学函数可以直接对数组进行操做,将原本须要在Python级别进行的循环,放到C语言的运算中,明显地提升了程序的运算速度。python
二、为何要用Numpy
NumPy是Python中的一个运算速度很是快的一个数学库,它很是重视数组。它容许你在Python中进行向量和矩阵计算,而且因为许多底层函数其实是用C编写的,所以你能够体验在原生Python中永远没法体验到的速度。api
import numpy as np import time # 用python自带方法处理 def func(values): result = [] for v in values: result.append(v * v) return result data = range(10000) %timeit func(data) 运行结果: 1.07 ms ± 20.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # 用numpy中的方法处理 arr = np.arange(0,10000) %timeit arr ** arr 运行结果: 397 µs ± 32.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
NumPy绝对是科学Python成功的关键之一,若是你想要进入Python中的数据科学或机器学习,你就要必须学习它。从最后的执行结果来看numpy的处理速度要比python的处理速度快上十几倍,固然这只是它的其中一项优点,下面就经过一些具体的操做来看一看numpy的用法与优点。数组
三、怎么用Numpy
安装方法:数据结构
pip install numpy架构
引用方式:app
import numpy as npdom
这是官方认证的导入方式,可能会有人说为何不用from numpy import *
,是由于在numpy当中有一些方法与Python中自带的一些方法,例如max
、min
等冲突,为了不这些麻烦你们就约定俗成的都使用这种方法。机器学习
Numpy的核心特征就是N-维数组对——ndarray.ide
3.一、为何要用ndarray?
numpy全部的操做都是围绕着数组展开的,这个数组的名字就叫作ndarray
,在学习ndarray数组以前确定有人会说这个东西和Python中的列表差很少啊,为何不用列表呢,列表还要方便些。其实列表list自己是为了处理更普遍、更通用的目的而构建的,其实从这一方面来看ndarray对于处理这个数组类型结构的数据会更加方便。
接下来咱们能够经过具体的实例来展现一下ndarray的优点。 如今有这样一个需求:
已知若干家跨国公司的市值(美圆),将其换算为人民币
按照Python当中的方法 第一种:是将全部的美圆经过for循环依次迭代出来,而后用每一个公司的市值乘以汇率 第二种:经过map方法和lambda函数映射
这些方法相对来讲也挺好用的,可是再来看经过ndarray对象是如何计算的
经过ndarray这个多维数组对象可让这些批量计算变得更加简单,固然这只它其中一种优点,接下来就经过具体的操做来发现。
3.二、ndarray-建立
方法 | 描述 |
---|---|
array() | 将列表转换为数组,可选择显式指定dtype |
arange() | range的numpy版,支持浮点数 |
linspace() | 相似arange(),第三个参数为数组长度 |
zeros() | 根据指定形状和dtype建立全0数组 |
ones() | 根据指定形状和dtype建立全1数组 |
empty() | 根据指定形状和dtype建立空数组(随机值) |
eye() | 根据指定边长和dtype建立单位矩阵 |
一、arange(): np.arange(1.2,10,0.4) 执行结果: array([1.2, 1.6, 2. , 2.4, 2.8, 3.2, 3.6, 4. , 4.4, 4.8, 5.2, 5.6, 6. , 6.4, 6.8, 7.2, 7.6, 8. , 8.4, 8.8, 9.2, 9.6]) # 在进行数据分析的时候一般咱们遇到小数的机会远远大于遇到整数的机会,这个方法与Python内置的range的使用方法同样 ----------------------------------------------------------------- 二、linspace() np.linspace(1,10,20) 执行结果: array([ 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. ]) # 这个方法与arange有一些区别,arange是顾头不顾尾,而这个方法是顾头又顾尾,在1到10之间生成的二十个数每一个数字之间的距离相等的,先后两个数作减法确定相等 ---------------------------------------------------------------- 三、zeros() np.zeros((3,4)) 执行结果: array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]]) # 会用0生成三行四列的一个多维数组 --------------------------------------------------------------------- 四、ones() np.ones((3,4)) 执行结果: array([[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]]) # 会用1生成三行四列的一个多维数组 ------------------------------------------------------------------------ 五、empty() np.empty(10) 执行结果: array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) # 这个方法只申请内存,不给它赋值 ----------------------------------------------------------------------- 六、eye() np.eye(5) 执行结果: 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.]]) # 对角矩阵
3.三、ndarray是一个多维数组列表
接下来就多维数组举个例子:
为了建立一个2维数组,咱们是传递了一个列表的列表给这个array()函数。若是咱们想要的是一个三维数组,咱们就必需要一个列表的列表的列表(也就是三层列表),以此类推。
不少状况下,处理一个新的维度只须要在numpy函数的参数中添加一个逗号
有的人可能会说了,这个数组跟Python中的列表很像啊,它和列表有什么区别呢?
''' 在python中列表是能够存任意类型的值的,可是在数组当中的元素必须类型必须相同。这是由于列表中存的只是每一个元素的地址,无论运行多少次,值的位置是不会改变的,不须要在乎数据的类型;而在ndarray当中存的是具体的值,每一次执行都是从新存放。 ''' l1 = ['1','2',4] na = np.array(l1) print(f"ndarry:{id(na[0])}") print(f"list:{id(l1[0])}") > ndarry:2140960887632 list:2140897577592 """ 经过屡次执行其实就能够发现,ndarray数组的id值一直在不停的换,而list的id值始终保持不变 """
- 数组对象内的元素类型必须相同
- 数组大小不可修改
3.四、经常使用属性
属性 | 描述 |
---|---|
T | 数组的转置(对高维数组而言) |
dtype | 数组元素的数据类型 |
size | 数组元素的个数 |
ndim | 数组的维数 |
shape | 数组的维度大小(以元组形式) |
itemsize | 每一个项占用的字节数 |
nbytes | 数组中的全部数据消耗掉的字节数 |
# T:转置 转置是一种特殊的数据重组形式,能够返回底层数据的视图而不须要复制任何内容。 # 通俗点说,转置就是将数据旋转90度,行变成列,列变成行。 li1 = [ [1,2,3], [4,5,6] ] a = np.array(li1) a.T 执行结果: array([[1, 4], [2, 5], [3, 6]])
# dtype:返回当前数据的数据类型 arr = np.arange(10) arr.dtype 执行结果: dtype('int32') # size:返回当前数组内存在的元素个数 l1 = [[[1,2,3], [4,5,6]], [[7,8,9], [1,5,9] ]] arr1 = np.array(l1) arr1.size 执行结果: 12 # ndim:返回当前数组维度 l1 = [[[1,2,3], [4,5,6]], [[7,8,9], [1,5,9] ]] arr1 = np.array(l1) arr1.ndim 执行结果: 3 # shape:返回数组维度大小 l1 = [[[1,2,3,4], [4,5,6,5], [6,8,3,6]], [[7,8,9,7], [1,5,9,7], [4,6,8,4] ]] arr1 = np.array(l1) arr1.shape 执行结果: (2, 3, 4) """ 最终三个参数表明的含义依次为:二维维度,三维维度,每一个数组内数据大小 要注意这些数组必需要是相同大小才能够 """
3.五、数据类型
- dtype
类型 | 描述 |
---|---|
布尔型 | bool_ |
整型 | int_ int8 int16 int32 int 64 |
无符号整型 | uint8 uint16 uint32 uint64 |
浮点型 | float_ float16 float32 float64 |
整型: int32只能表示(-2**31,2**31-1),由于它只有32个位,只能表示2**32个数 无符号整型: 只能用来存正数,不能用来存负数 """ 补充: astype()方法能够修改数组的数据类型 示例: data.astype(np.float) """
3.六、向量化数学运算
- 数组和标量(数字)之间运算
li1 = [ [1,2,3], [4,5,6] ] a = np.array(li1) a * 2 运行结果: array([[ 2, 4, 6], [ 8, 10, 12]])
与标量之间进行向量化运算,多维数组与一维数组没有任何区别,都会将你要运算的数字映射到数组中的每个元素上进行运算
- 一样大小数组之间的运算
# l2数组 l2 = [ [1,2,3], [4,5,6] ] a = np.array(l2) # l3数组 l3 = [ [7,8,9], [10,11,12] ] b = np.array(l3) a + b # 计算 执行结果: array([[ 8, 10, 12], [14, 16, 18]])
数组与数组之间的向量化运算,两个运算的数组必须相同大小,不然会报错
3.七、索引和切片
- 索引
一维索引使用与python自己的列表没有任何区别,因此接下来主要针对大的是多维数组
# np重塑 arr = np.arange(30).reshape(5,6) # 后面的参数6能够改成-1,至关于占位符,系统能够自动帮忙算几列
# 将二维变一维 arr.reshape(30) # 索引使用方法 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]]) 如今有这样一组数据,需求:找到20 列表写法:arr[3][2] 数组写法:arr[3,2] # 中间经过逗号隔开就能够了
- 切片
arr数组 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]]) arr[0,1:4] # >>array([1, 2, 3]) arr[1:4,0] # >>array([ 6, 12, 18]) arr[::2,::2] # >>array([[ 0, 2, 4], # [12, 14, 16], # [24, 26, 28]]) arr[:,1] # >>array([ 1, 7, 13, 19, 25])
切片不会拷贝,直接使用的原视图,若是硬要拷贝,须要在后面加.copy()方法
最后会发现修改切片后的数据影响的依然是原数据。有的人可能对一点机制有一些不理解的地方,像Python中内置的都有赋值的机制,而Numpy去没有,实际上是由于NumPy的设计目的是处理大数据,因此你能够想象一下,假如NumPy坚持要将数据复制来复制去的话会产生何等的性能和内存问题。
- 布尔型索引
如今有这样一个需求:给一个数组,选出数组种全部大于5的数。
li = [random.randint(1,10) for _ in range(30)] a = np.array(li) a[a>5] 执行结果: array([10, 7, 7, 9, 7, 9, 10, 9, 6, 8, 7, 6]) ---------------------------------------------- 原理: a>5会对a中的每个元素进行判断,返回一个布尔数组 a > 5的运行结果: array([False, True, False, True, True, False, True, False, False, False, False, False, False, False, False, True, False, True, False, False, True, True, True, True, True, False, False, False, False, True]) ---------------------------------------------- 布尔型索引:将一样大小的布尔数组传进索引,会返回一个有True对应位置的元素的数组
布尔型索引是numpy当中的一个很是经常使用的用法,经过布尔型索引取值方便又快捷。
四、通用函数
能对数组中全部元素同时进行运算的函数就是通用函数
4.一、常见通用函数
可以接受一个数组的叫作一元函数,接受两个数组的叫二元函数,结果返回的也是一个数组
- 一元函数:
函数 | 功能 |
---|---|
abs、fabs | 分别是计算整数和浮点数的绝对值 |
sqrt | 计算各元素的平方根 |
square | 计算各元素的平方 |
exp | 计算各元素的指数e**x |
log | 计算天然对数 |
sign | 计算各元素的正负号 |
ceil | 计算各元素的ceiling值 |
floor | 计算各元素floor值,即小于等于该值的最大整数 |
rint | 计算各元素的值四舍五入到最接近的整数,保留dtype |
modf | 将数组的小数部分和整数部分以两个独立数组的形式返回,与Python的divmod方法相似 |
isnan | 判断数组中的缺失值 |
isinf | 表示那些元素是无穷的布尔型数组 |
cos,sin,tan | 普通型和双曲型三角函数 |
如下简单演示经常使用的几个一元函数:
# 计算整数绝对值 arr = np.random.randint(-10,10,20) np.abs(arr) > array([9, 7, 3, 1, 5, 8, 7, 9, 4, 2, 7, 3, 4, 6, 6, 9, 2, 5, 8, 1]) ------------------------------------------------------------------------------- # 计算浮点数绝对值 arr = np.random.randn(2,5) np.fabs(arr) > array([[0.09892302, 0.06200835, 1.0324653 , 1.58089607, 0.44506652], [0.34897694, 1.04843539, 0.83976969, 0.4731551 , 0.92229931]]) ------------------------------------------------------------------------------ # 计算各元素的平方根 arr = np.arange(10) np.sqrt(arr) > array([0. , 1. , 1.41421356, 1.73205081, 2. , 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
- 二元函数:
函数 | 功能 |
---|---|
add | 将数组中对应的元素相加 |
subtract | 从第一个数组中减去第二个数组中的元素 |
multiply | 数组元素相乘 |
divide、floor_divide | 除法或向下圆整除法(舍弃余数) |
power | 对第一个数组中的元素A,根据第二个数组中的相应元素B计算A**B |
maximum,fmax | 计算最大值,fmax忽略NAN |
miximum,fmix | 计算最小值,fmin忽略NAN |
mod | 元素的求模计算(除法的余数) |
arr = np.random.randint(0,10,5) arr1 = np.random.randint(0,10,5) arr,arr1 > (array([0, 1, 8, 2, 6]), array([5, 4, 1, 7, 0])) ------------------------------------------------------------------------- # add 将数组中对应的元素相加 np.add(arr,arr1) > array([5, 5, 9, 9, 6]) ------------------------------------------------------------------------- # subtract 从第一个数组中减去第二个数组中的元素 np.subtract(arr,arr1) > array([-5, -3, 7, -5, 6]) ------------------------------------------------------------------------- # multiply 数组元素相乘 np.multiply(arr,arr1) > array([ 0, 4, 8, 14, 0]) ------------------------------------------------------------------------- ...
补充内容:浮点数特殊值
浮点数:float 浮点数有两个特殊值:
一、nan(Not a Number):不等于任何浮点数(nan != nan) --------------------------------------------- 二、inf(infinity):比任何浮点数都大 ---------------------------------------------
- Numpy中建立特殊值:np.nan、np.inf
- 数据分析中,nan常被用做表示数据缺失值
以上函数使用很是方便,使用这些方法可让数据分析的操做更加便捷。
4.二、数学统计方法
函数 | 功能 |
---|---|
sum | 求和 |
cumsum | 求前缀和 |
mean | 求平均数 |
std | 求标准差 |
var | 求方差 |
min | 求最小值 |
max | 求最大值 |
argmin | 求最小值索引 |
argmax | 求最大值索引 |
arr = np.random.randint(0,10,10) arr > array([2, 9, 6, 5, 4, 2, 9, 8, 0, 5]) ------------------------------------------------------------------------- # sum 求和 np.sum(arr) > 50 ------------------------------------------------------------------------- # cumsum 求前缀和 np.cumsum(arr) array([ 2, 11, 17, 22, 26, 28, 37, 45, 45, 50], dtype=int32) # 依次累加 ------------------------------------------------------------------------- # mean 求平均数 np.mean(arr) > 5.0 ------------------------------------------------------------------------- # 因为此档内容太过简单,后续就不一一展现了 ...
4.三、随机数
咱们有学过python中生成随机数的模块random,在numpy中也有一个随机数生成函数,它在**np.random
**的子包当中。在Python自带的random当中只能生成一些简单、基础的随机数,而在np.random当中是能够生成一些高级的随机数的。np.random要比Python自带的random包更加灵活。
函数 | 功能 |
---|---|
rand | 返回给定维度的随机数组(0到1之间的数) |
randn | 返回给定维度的随机数组 |
randint | 返回给定区间的随机整数 |
choice | 给定的一维数组中随机选择 |
shuffle | 原列表上将元素打乱(与random.shuffle相同) |
uniform | 给定形状产生随机数组 |
seed | 设定随机种子(使相同参数生成的随机数相同) |
standard_normal | 生成正态分布的随机样本数 |
# rand 返回给定维度的随机数组 np.random.rand(2,2,2) > array([[[0.37992696, 0.18115096], [0.78854551, 0.05684808]], [[0.69699724, 0.7786954 ], [0.77740756, 0.25942256]]]) ------------------------------------------------------------------------- # randn 返回给定维度的随机数组 np.random.randn(2,4) > array([[ 0.76676877, 0.21752554, 2.08444169, 1.51347609], [-2.10082473, 1.00607292, -1.03711487, -1.80526763]]) ------------------------------------------------------------------------- # randint 返回给定区间的随机整数 np.random.randint(0,20) > 15 ------------------------------------------------------------------------- # chocie 给定的一维数组中随机选择 np.random.choice(9,3) # # 从np.range(9)中,(默认)有放回地等几率选择三个数 > array([5, 8, 2]) np.random.choice(9,3,replace=False) # 无放回地选择 > array([1, 2, 0]) ------------------------------------------------------------------------ # shuffle 原列表上将元素打乱(与random.shuffle相同) arr = np.arange(10) np.random.shuffle(arr) arr > array([4, 5, 0, 3, 7, 8, 9, 1, 2, 6]) ------------------------------------------------------------------------ # uniform 给定形状产生随机数组 np.random.uniform(0,1,[3,3,3]) > array([[[0.80239474, 0.37170323, 0.5134832 ], [0.42046889, 0.40245839, 0.0812019 ], [0.8788738 , 0.48545176, 0.73723353]], [[0.79057724, 0.80644632, 0.65966656], [0.43833643, 0.53994887, 0.46762885], [0.44472436, 0.08944074, 0.34148912]], [[0.7042795 , 0.58397044, 0.13061102], [0.22925123, 0.97745023, 0.14823085], [0.6960559 , 0.07936633, 0.91221842]]]) ------------------------------------------------------------------------ # seed 设定随机种子(使相同参数生成的随机数相同) np.random.seed(0) # 当seed(0)时生成如下随机数组 np.random.rand(5) > array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ]) np.random.seed(2) # send(5)时生成如下随机数组 np.random.rand(5) > array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ]) np.random.seed(0) # 再次使用send(0)会发现返回最开始的随机数组 np.random.rand(5) > array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ]) ------------------------------------------------------------------------ # standard_normal 生成正态分布的随机样本数 np.random.standard_normal([2,10]) > array([[-0.17937969, -0.69277058, 1.13782687, -0.16915725, -0.76391367, -0.4980731 , -0.36289111, 0.26396031, -0.62964191, -0.4722584 ], [-1.51336104, 1.10762468, 0.17623875, -0.94035354, 0.92959433, -1.06279492, -0.88640627, 1.92134696, -0.45978052, -1.08903444]])
np.random和Python原生的random的区别:
比较内容 | random | np.random |
---|---|---|
输入类型 | 非空的列表类型(包括列表、字符串和元组) | 非空的列表类型(包括列表、字符串和元组)+ numpy.array类型 |
输出维度 | 一个数或一个list(多个数) | 可指定复杂的size |
指定(a,b)范围 | 能够 | 整数可指定,浮点数不行,需自行转换 |
批量输出 | 不可 | 可。经过指定size参数 |
特定分布 | 涵盖了经常使用的几个分布; 只能单个输出 | 几乎涵盖了全部分布;可批量输出 |
只要能把以上全部的内容掌握,数据分析这门功夫你就算是打通了任督二脉了,学起来轻松又愉快。
五、数据表示
全部须要处理和构建模型所需的数据类型(电子表格、图像、音频等),其中不少都适合在 n 维数组中表示:
表格和电子表格
表格和电子表格是二维矩阵。电子表格中的每一个工做表均可以是它本身的变量。python 中最流行的抽象是 pandas 数据帧,它实际上使用了 NumPy 并在其之上构建。
音频和时间序列
音频文件是样本的一维数组。每一个样本都是一个数字,表明音频信号的一小部分。CD 质量的音频每秒包含 44,100 个样本,每一个样本是-65535 到 65536 之间的整数。这意味着若是你有一个 10 秒的 CD 质量 WAVE 文件,你能够将它加载到长度为 10 * 44,100 = 441,000 的 NumPy 数组中。若是想要提取音频的第一秒,只需将文件加载到 audio 的 NumPy 数组中,而后获取 audio[:44100]。
如下是一段音频文件:
时间序列数据也是如此(如股票价格随时间变化)。
图像
图像是尺寸(高度 x 宽度)的像素矩阵。
若是图像是黑白(即灰度)的,则每一个像素均可以用单个数字表示(一般在 0(黑色)和 255(白色)之间)。想要裁剪图像左上角 10 x 10 的像素吗?在 NumPy 写入便可。
下图是一个图像文件的片断:
若是图像是彩色的,则每一个像素由三个数字表示——红色、绿色和蓝色。在这种状况下,咱们须要一个三维数组(由于每一个单元格只能包含一个数字)。所以彩色图像由尺寸为(高 x 宽 x3)的 ndarray 表示:
六、总结
使用numpy,能够为咱们提供一组丰富而又灵活的数据结构,以金融的角度来看的话下面几种类型是最重要的:
基本数据类型
在金融量化当中,整数、浮点数和字符串给咱们提供了原子数据类型
标准数据结构
元组、列表、字典和集合,这些在金融当中有许多应用领域,列表一般是最为经常使用的
数组
说到数组确定就是今天所学习的numpy中的ndarray数组,它对于数据的处理性能更高,代码更简洁、方便
原文出处:https://www.cnblogs.com/guapitomjoy/p/12198706.html