成为华尔街金融巨鳄第一课:学会使用NumPy

成为华尔街金融巨鳄第一课:学会使用NumPy

一、为什么要使用numpy

import numpy as np # 导包

分析如下两个例子,numpy提供的方式将大大简便操作

例1:已知若干家跨国公司的市值(美金),将其转换为人民币

例2:已知购物车中的每件商品的价格与商品件数,求总金额

numpy提供了ndarray(多维数组)对象
创建ndarray: np.array(array_like)
数组与列表的区别:
    数组:元素类型必须相同,大小不可修改 列表:元素类型可以不同,可以通过append添加元素

二、ndarray相关属性

import random
a = np.array(range(10))

属性

a.dtype #数组类型
dtype('int32')
a.size #数组大小
10
a = np.array([[1,2,3],[4,5,6]]) # 创建二维数组
a
array([[1, 2, 3],
       [4, 5, 6]])
a.size 
6
a.shape #数组的形状为2行3列
(2, 3)
a = a.T #数组转置(行变列,列边行)
a
array([[1, 4],
       [2, 5],
       [3, 6]])
a.ndim #查看尾数
2

三、数组的创建

方法一:直接用python列表创建

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

方法二:创建全为0或1的数组

# 愚蠢的列表创建方法
np.array([0]*10) 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# 机智的numpy创建方法
a = np.zeros(10)
a
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
# 注意事项
# 1.numpy绝大部分运算要使用小数运算,所以自动创建的为浮点类型的0
a.dtype
dtype('float64')
# 2.如果实在想创建整型,如下
a = np.zeros(10,dtype='int')
a
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# 3.仿照上面的内容,创建10个元素全为1的数组
np.ones(10)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

方法三:np.empty

np.empty(100)
array([1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.])
注意事项:empty函数向内存申请空间,我们所看到的数值均为内存中残存的数值

方法四:类range方法创建:np.arange

# 创建从0到100的数组
np.arange(100)
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, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
       68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
       85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])
# 创建从2到100的数组(左闭右开)
np.arange(2,100)
array([ 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,
       36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
       53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
       70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
       87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])
# 创建从0到100,步长为2的数组
np.arange(0,100,2)
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
       34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,
       68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98])
参数说明:
1.第一个参数为起始值,第二个参数为终了值,第三个参数为步长
2.三个参数均可以为浮点类型(python range无此功能)

例:

np.arange(1.2,100.6,1.5)
array([  1.2,   2.7,   4.2,   5.7,   7.2,   8.7,  10.2,  11.7,  13.2,
        14.7,  16.2,  17.7,  19.2,  20.7,  22.2,  23.7,  25.2,  26.7,
        28.2,  29.7,  31.2,  32.7,  34.2,  35.7,  37.2,  38.7,  40.2,
        41.7,  43.2,  44.7,  46.2,  47.7,  49.2,  50.7,  52.2,  53.7,
        55.2,  56.7,  58.2,  59.7,  61.2,  62.7,  64.2,  65.7,  67.2,
        68.7,  70.2,  71.7,  73.2,  74.7,  76.2,  77.7,  79.2,  80.7,
        82.2,  83.7,  85.2,  86.7,  88.2,  89.7,  91.2,  92.7,  94.2,
        95.7,  97.2,  98.7, 100.2])

方法五:numpy线性空间:np.linspace

#创建从0到10,并且分割为11份的数组
a = np.linspace(0,10,11)
a
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
a.size
11
#创建从0到10.5,并且分割为150份的数组
a = np.linspace(0,10.5,50)
a
array([ 0.        ,  0.21428571,  0.42857143,  0.64285714,  0.85714286,
        1.07142857,  1.28571429,  1.5       ,  1.71428571,  1.92857143,
        2.14285714,  2.35714286,  2.57142857,  2.78571429,  3.        ,
        3.21428571,  3.42857143,  3.64285714,  3.85714286,  4.07142857,
        4.28571429,  4.5       ,  4.71428571,  4.92857143,  5.14285714,
        5.35714286,  5.57142857,  5.78571429,  6.        ,  6.21428571,
        6.42857143,  6.64285714,  6.85714286,  7.07142857,  7.28571429,
        7.5       ,  7.71428571,  7.92857143,  8.14285714,  8.35714286,
        8.57142857,  8.78571429,  9.        ,  9.21428571,  9.42857143,
        9.64285714,  9.85714286, 10.07142857, 10.28571429, 10.5       ])
对比arange了解参数说明:
1.第一个参数为起始值,第二个参数为终了值,注意linspace为全闭区间,而arange为左闭右开区间
2.第三个参数为创建的数组大小(size)
3.三前两个参数均可以为浮点类型,第三个参数必须为整形
4.linspace的含义:将a到b分割为c个数,两两之间的差值相等

例:

在以下这个例子中,我们将向你展示如何使用linspace做出函数图像以便更好地理解这个函数,众所周知函数图像为连续的无穷点构成的图像,而计算机无法绘制出无穷点,因此我们可以以足够大的有穷代无穷
通过这个例子,你将会理解为什么区间需要用闭区间,以及分割的具体含义,理论上讲如果分割成无数个点就可以表示在数学上的一段数轴

x = np.linspace(-10,10,100000)
x
array([-10.    ,  -9.9998,  -9.9996, ...,   9.9996,   9.9998,  10.    ])
# 绘制y=x**2,定义域为-10到10的图像
y = x**2
y
array([100.        ,  99.996     ,  99.99200008, ...,  99.99200008,
        99.996     , 100.        ])
import matplotlib.pyplot as plt
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x192fc547848>]

在这里插入图片描述

方法六:生成单位矩阵

# 生成线性代数中的单位矩阵
np.eye(10)
array([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]])

四、ndarray批量运算与索引切片

a = np.arange(0,10)
a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b = np.arange(10,20)
b
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])

1、与标量进行运算

a+1
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
a*2
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
a/3
array([0.        , 0.33333333, 0.66666667, 1.        , 1.33333333,
       1.66666667, 2.        , 2.33333333, 2.66666667, 3.        ])

2、与数组进行运算

# 对应元素相加
a+b
array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28])
# 对应元素比大小,返回布尔值
a>b
array([False, False, False, False, False, False, False, False, False,
       False])

3、索引与切片

# 一维数组的索引
a[1]
1
# 二维数组的索引
c = np.arange(15).reshape((3,5))
# reshape函数:重塑数组,将0到15的一维数组重塑为3行5列,注意参数为元组
c
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
# 以下两种写法均可
c[0][0]
0
c[0,0]
0
# 取出12这个数
c[2,2]
12
a = np.arange(15)
a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
#一维数组的切片
a[0:4]
array([0, 1, 2, 3])
a[:4]
array([0, 1, 2, 3])
a[4:]
array([ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
# 对比列表理解一维数组的切片
# 使用方法和列表切片类似
a = np.arange(10)
b = list(range(10))
a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
c = a[0:4]
d = b[0:4]
c
array([0, 1, 2, 3])
d
[0, 1, 2, 3]
c[0]=20
d[0]=20
c
array([20,  1,  2,  3])
d
[20, 1, 2, 3]
a
array([20,  1,  2,  3,  4,  5,  6,  7,  8,  9])
b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#切片注意事项1: 在对数组进行切片时进行的是浅拷贝,而列表切片是深拷贝,也就是上面所示修改切片后的c的元素会影响a的值

在使用numpy进行科学计算时,往往数值大,数量多,因此使用深拷贝会大大增加运行时间并且占用内存,因而在默认情况下一般都是浅拷贝,如果一定要使用深拷贝可以使用下面的copy函数

c = a[0:4].copy()
c
array([20,  1,  2,  3])
a
array([20,  1,  2,  3,  4,  5,  6,  7,  8,  9])
c[0]=0
c
array([0, 1, 2, 3])
a
array([20,  1,  2,  3,  4,  5,  6,  7,  8,  9])
# 二维数组的切片
a = np.arange(15).reshape((3,5))
a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
目标:切出
0,1
5,6
a[0:2,0:2]
array([[0, 1],
       [5, 6]])
#切片注意事项2: a[m:n,x:y]指从第m行切到第n行,第x列切到第y列,注意索引从0开始,且任然是左闭右开,逗号左边是行右边是列

固a[0:2,0:2]指从行数取区间[0,2)的整数,列数取区间[0,2)的整数。

# 类似于列表切片,:前后不赋值默认从最前面开始取(取到最后)
a[1:,:3]
array([[ 5,  6,  7],
       [10, 11, 12]])

4、布尔型索引

引入问题:选出给定数组中所有大于5的数

python给出的解决方案:

a = [random.randint(0,10) for i in range(20)]
a
[3, 7, 5, 5, 4, 5, 4, 9, 7, 5, 4, 7, 10, 7, 6, 8, 3, 10, 4, 4]
list(filter(lambda x : x>5,a))
[7, 9, 7, 7, 10, 7, 6, 8, 10]

numpy给出的解决方案:

a = np.array(a)
a
array([ 3,  7,  5,  5,  4,  5,  4,  9,  7,  5,  4,  7, 10,  7,  6,  8,  3,
       10,  4,  4])
a[a>5]
array([ 7,  9,  7,  7, 10,  7,  6,  8, 10])
原理解释:
# 回忆numpy标量运算,a>5:# 所有元素与5比大小,返回布尔值
a>5
array([False,  True, False, False, False, False, False,  True,  True,
       False, False,  True,  True,  True,  True,  True, False,  True,
       False, False])
# 了解布尔索引
# a[b]:b为与a长度一样的数组或列表,b中的元素均为布尔类型,a会返回True对应位置的元素
a = np.arange(4)
a
array([0, 1, 2, 3])
b = [True,False,True,False]
a[b]
array([0, 2])
a[[False,False,True,True]]
array([2, 3])
问题2:选出给定数组中所有大于5的偶数
a = [random.randint(0,10) for i in range(20)]
a = np.array(a)
a
array([ 0,  2,  8,  1,  1,  2,  2,  8,  9,  1, 10,  3,  0,  5,  3,  3,  4,
       10,  4,  8])
b = a[a>5]
b
array([ 8,  8,  9, 10, 10,  8])
b[b%2==0]
array([ 8,  8, 10, 10,  8])

是否可以简化合并成一行?
尝试:

 a[a>5][a%2==0]
---------------------------------------------------------------------------

IndexError                                Traceback (most recent call last)

<ipython-input-362-109e9a75f8d4> in <module>
----> 1 a[a>5][a%2==0]


IndexError: boolean index did not match indexed array along dimension 0; dimension is 6 but corresponding boolean dimension is 20
报错原因:
# 首先看下a%2==0的size
a%2==0
array([ True,  True,  True, False, False,  True,  True,  True, False,
       False,  True, False,  True, False, False, False,  True,  True,
        True,  True])
(a%2==0).size
20
# 再来看 a[a>5]的size
a[a>5]
array([ 8,  8,  9, 10, 10,  8])
a[a>5].size
6

显然两者size不等无法连续使用布尔索引,那是否有其他方案

a[(a>5) & a%2==0)]
array([ 8,  8, 10, 10,  8])
a[(a>5) and (a%2==0)]
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-376-fee222ad41de> in <module>
----> 1 a[(a>5) and (a%2==0)]


ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
#注意事项:1.记得加括号,因为&运算级更高 2.不得使用and 3.取反是~
# 或运算 |
a[(a>5) | (a%2==0)]
array([ 0,  2,  8,  2,  2,  8,  9, 10,  0,  4, 10,  4,  8])

五、花式索引

引入问题:选出给定数组中的1,3,4,6,7号元素,组成新的二维数组
a = np.arange(20)
a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19])
# 一维数组花式索引:a[list(m)]去取出数组a中列表m元素对应索引的元素
# 注意是中括号嵌套中括号,因为一般情况下,最外层中括号里面的逗号用以分割行列,如切片中的a[0:2,0:2]
a[[1,3,4,6,7]]
array([1, 3, 4, 6, 7])
# 二维数组花式索引
a = a.reshape(4,5)
a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
# 所谓花式索引就是将之前的所有索引方式搭配使用,只需记住“,”前面表示行,后面表示列
# 回顾普通索引 a[m,n]表示第m行第n列索引 a[m]表示第m行元素 如:
a[0]
array([0, 1, 2, 3, 4])
# 回顾切片索引
a[0:2,1:4]
array([[1, 2, 3],
       [6, 7, 8]])
# 回顾布尔索引
a[[True,False,True,False]]
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14]])
a[a>2]
array([ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
# 搭配使用
# 普通索引与切片索引搭配
a[0,2:]
array([2, 3, 4])
# 普通索引与布尔索引搭配
a[0]>2
array([False, False, False,  True,  True])
a[0,a[0]>2]
array([3, 4])
# 一维花式索引与且切片索引搭配
a[[1,3],2:]
array([[ 7,  8,  9],
       [17, 18, 19]])
#禁忌:禁止逗号两边同时使用花式索引

例如:取6,8,16,18这几个数字

a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
# 两边同时使用花式索引,会出现以下情况
a[[1,3],[1,3]]
array([ 6, 18])
# 只能像下面这么取
a[[1,3],:][:,[1,3]]
array([[ 6,  8],
       [16, 18]])

六、numpy常函数

1.np.abs():取绝对值函数 对每个元素取绝对值
2.np.sqrt():开方函数 对每个元素开方
3.np.floor():向下取整 
4.np.ceil():向上取整
5.np.round()/np.rint():四舍五入
6.np.trunc():向0取整
7.np.modf():返回两个数组,分割小数部分和整数部分

eg.

a = np.arange(-5.5,5.5)
a
array([-5.5, -4.5, -3.5, -2.5, -1.5, -0.5,  0.5,  1.5,  2.5,  3.5,  4.5])
x,y = np.modf(a)
print(x,y)
np.modf(a)
[-0.5 -0.5 -0.5 -0.5 -0.5 -0.5  0.5  0.5  0.5  0.5  0.5] [-5. -4. -3. -2. -1. -0.  0.  1.  2.  3.  4.]





(array([-0.5, -0.5, -0.5, -0.5, -0.5, -0.5,  0.5,  0.5,  0.5,  0.5,  0.5]),
 array([-5., -4., -3., -2., -1., -0.,  0.,  1.,  2.,  3.,  4.]))
#向数轴左边取整
np.floor(a)
array([-6., -5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
#向数轴右边取整
np.ceil(a)
array([-5., -4., -3., -2., -1., -0.,  1.,  2.,  3.,  4.,  5.])
np.round(a)
array([-6., -4., -4., -2., -2., -0.,  0.,  2.,  2.,  4.,  4.])
np.trunc(a)
array([-5., -4., -3., -2., -1., -0.,  0.,  1.,  2.,  3.,  4.])
np.sqrt(a)
C:\Users\Lenovo\miniconda3\lib\site-packages\ipykernel_launcher.py:1: RuntimeWarning: invalid value encountered in sqrt
  """Entry point for launching an IPython kernel.





array([       nan,        nan,        nan,        nan,        nan,
              nan, 0.70710678, 1.22474487, 1.58113883, 1.87082869,
       2.12132034])
np.abs(a)
array([5.5, 4.5, 3.5, 2.5, 1.5, 0.5, 0.5, 1.5, 2.5, 3.5, 4.5])



补充——浮点数的特殊值:
nan(Not a Number):代表不等于任何浮点数 甚至不等于自己
inf : 无穷大,比任何值都大 但是等于自己
np.nan == np.nan
False
a = np.array([0,1,1,1,1])
a
array([0, 1, 1, 1, 1])
b = a/a
b
C:\Users\Lenovo\miniconda3\lib\site-packages\ipykernel_launcher.py:1: RuntimeWarning: invalid value encountered in true_divide
  """Entry point for launching an IPython kernel.





array([nan,  1.,  1.,  1.,  1.])
# 如何判断是否存在nan?
b == np.nan
array([False, False, False, False, False])
# 显然上面这种方法不行
# numpy提供了np.isnan()函数用以判断nan类型
np.isnan(b)
array([ True, False, False, False, False])
# 练习:选出数组b里所有数字
b[~(np.isnan(b))]
array([1., 1., 1., 1.])
np.maximum/minimun(a,b,c,…)函数:取出对应元素的最大/小值并构成新的数组
a = np.array([3,5,7,6,3])
b = np.array([2,6,8,4,3])
np.maximum(a,b)
array([3, 6, 8, 6, 3])
np.minimum(a,b)
array([2, 5, 7, 4, 3])

七、numpy数学和统计方法

a = np.array([3,5,7,6,3])
a
array([3, 5, 7, 6, 3])
# 求和
a.sum()
24
# 求均值
a.mean()
4.8
# 求标准差
a.std()
1.6
# 求方差
a.var()
2.56
# 求最小值
a.min()
3
# 求最大值
a.max()
7
# 求最小值索引
a.argmin()
0
# 求最大值索引
a.argmax()
2
# 随机数生成
np.random.randint(0,10)
4
np.random.randint(0,10,5)
array([7, 1, 7, 9, 5])
a = np.random.randint(0,10,(5,4))
a
array([[9, 3, 3, 7],
       [4, 8, 3, 0],
       [8, 6, 1, 1],
       [2, 3, 9, 1],
       [5, 4, 5, 1]])
# 洗牌
np.random.shuffle(a)
a
array([[5, 4, 5, 1],
       [8, 6, 1, 1],
       [4, 8, 3, 0],
       [9, 3, 3, 7],
       [2, 3, 9, 1]])
# 随机从列表抽
np.random.choice([1,3,5,6],10)
array([3, 5, 6, 5, 5, 6, 6, 3, 1, 3])

python random里所有的函数都被np.random()重写了所有功能

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这个人不主动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值