numpy模块

NumPy简介:

NumPy 是高性能科学计算和数据分析的基础包;它是pandas等其他工具的基础。

NumPy的主要功能:

1. ndarray,一个多维数组结构,高效且节省空间 (最主要的功能)
2. 无需循环对整组数据进行快速运算的数学函数
3. 线性代数、随机数生成和傅里叶变换功能

安装方法:

pip install numpy

引用方式:

import numpy as np

ndarray --- 多维数组对象

import numpy as np
创建 ndarray: np.array(array_like)

数组与列表的区别:

1. 数组对象内的元素类型必须相同
2. 数据大小不可修改

ndarray 的数据类型:

1. 布尔型:bool_
2. 整型:int_ int8 int16 int32 int64
3. 无符号整型:uint8 uint16 uint32 uint64
4. 浮点型:float_  float16 float32 float64
5. 复数型:complex_ complex64 complex128

array 基础:

示例代码1:(运行在 jupyter notebook 上)

import numpy as np
import random

# 示例1:已知若干跨国公司的市值(美元),将其换算成人民币
company_value = [random.uniform(100.0,200.0) for i in range(50)]  # random.uniform(浮点数1,浮点数2) : 随机生成浮点数

exchange_rate = 6.8

company_value = np.array(company_value)

company_value * exchange_rate   # company_value 这个列表中的每一个元素会都和 exchange_rate 相乘

"""
# 输出结果:

array([ 845.86596363,  830.59247689,  925.73635851,  994.17431358,
       1202.07839264, 1108.3175636 , 1135.15916313, 1171.85643304,
        743.06118207, 1213.00933088,  882.02326337, 1004.72845351,
        874.40129737,  722.8946267 , 1308.49169262, 1096.72738352,
       1231.12116846, 1255.03236732, 1077.22583737, 1323.68310872,
        765.1724099 , 1188.17611809,  940.02458512, 1141.96064667,
       1323.77261344, 1301.97767208,  969.35890194, 1291.7188247 ,
       1082.17748458,  961.91630791, 1158.81519619,  918.03641864,
        970.21533038, 1174.21974931, 1154.29890466, 1050.87454   ,
       1269.64470711,  850.13327118, 1021.26461162,  712.55711713,
       1156.62432585,  684.48019691,  996.70613004,  750.45285854,
       1243.63861422, 1304.56338027, 1156.27695066, 1235.00442836,
       1083.40377629,  783.09838542])
"""

示例代码2:(运行在 jupyter notebook 上)

# 示例2:已知购物车中每件端口的价格与商品件数,求总金额
import numpy as np
import random

unit_price = [random.uniform(10.0,20.0) for i in range(50)]
amount = [random.randint(1,10) for i in range(50)]

unit_price = np.array(unit_price)
amount = np.array(amount)

unit_price * amount  # unit_price 这个列表中的每一个元素都会和 amount 这个列表中的每一个元素相乘

(unit_price * amount).sum()  # .sum() 是 np.array 的求和

示例代码3:数组的属性(运行在 jupyter notebook 上)

# 数组的属性
import numpy as np
np.array([1,2,3,4,5])
# 输出结果:array([1, 2, 3, 4, 5])

np.array(range(10))
# 输出结果: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

a = np.array(range(10))
a.dtype  # 查看类型
# 输出结果: dtype('int32')

a.size  # 当前数组存了多少个数
# 输出结果: 10

np.array([[1,2,3,],[4,5,6,]])  # [[1,2,3,],[4,5,6,]] 是一个二维列表;np.array([[1,2,3,],[4,5,6,]]) 是一个二维数组
# 输出结果: array([[1, 2, 3],
#        [4, 5, 6]])

b= np.array([[1,2,3],[4,5,6]])
b.dtype
# 输出结果: dtype('int32')
b.size  # 返回总的元素个数
# 输出结果: 6
b.shape  # 返回的是 几乘几 (元组的形式),这是对于二维数组;对于一维数组而言,返回的是: (数组的长度,)
# 输出结果:(2, 3)  # 意思是 2行3列
b.T  # 数组的转置  (如:行变成列,列变成行)
"""
输出结果:
array([[1, 4],
       [2, 5],
       [3, 6]])
"""
b.ndim  # 查看当前维度
# 输出结果:  2

numpy-array 创建:

import numpy as np
# 以下方式中 np. 被省略
#方式1.:
array()  # 将列表转换为数组,可选择显式指定 dtype

# 方式2:
arange()  # python3 range的numpy版,支持浮点数

# 方式3:
linspace()  # 类似 np.arange() ,第三个参数为数组长度

# 方式4:
zeros()  # 根据指定形状和dtype创建全0数组
# 方式5:
ones()  # 根据指定形状和dtype创建全1数组

# 方式6:
empty()  # 根据指定形状和dtype创建空数组(随机值)

# 方式7:
eye()   # 根据指定形状和dtype创建单位矩阵

示例代码:(运行在jupytor notebook上)

# numpy-array 的创建
import numpy as np

# 方式一:
np.array([1,2,3])
# 输出结果: array([1, 2, 3])

# 方式二: 创建10个全0的数组 (数组中的元素默认为 浮点数 类型)
np.zeros(10)
# 输出结果: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
a = np.zeros(5)  
a.dtype 
# 输出结果: dtype('float64')

# 指定 元素类型
b = np.zeros(3,dtype="int64")
b.dtype
# 输出结果:dtype('int64')

# 方式三:创建5个全1的数组(默认为 浮点数 类型)
np.ones(5)
# 输出结果: array([1., 1., 1., 1., 1.])
c = np.ones(5)
c.dtype
# dtype('float64')

# 方式四:创建长度为10的空数组(随机值)
np.empty(20)
"""
# 输出结果:
array([1.42417221e-306, 1.37961641e-306, 1.24610383e-306, 1.69118108e-306,
       8.06632139e-308, 1.20160711e-306, 1.69119330e-306, 1.29062229e-306,
       1.60217812e-306, 1.37961370e-306, 1.78020712e-306, 8.90104239e-307,
       1.05700515e-307, 1.11261774e-306, 1.29060871e-306, 8.34424766e-308,
       8.34445138e-308, 1.37959129e-306, 1.02360528e-306, 8.90029544e-307])
"""
# np.empty() 的作用: 数组的大小(长度)是不能变的,所以创建数组时必须先指定好数组的长度,然后再往里面写入值; np.empty() 的效率比 np.zeros()高(速度快)


# 方式五:np.arange(起始值,结束值,步长)   # 步长可为 浮点数
np.arange(10)
# 输出结果: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(2,10)
# 输出结果: array([2, 3, 4, 5, 6, 7, 8, 9])
np.arange(3,10,2)
# 输出结果: array([3, 5, 7, 9])
np.arange(7,10,0.3)
# 输出结果: array([7. , 7.3, 7.6, 7.9, 8.2, 8.5, 8.8, 9.1, 9.4, 9.7])

# 方式六: np.linspace(起始值,结束值,分成多少份)  # 第三个参数“分成多少份”表示数组的长度
np.linspace(2,10,3)  
# 输出结果: array([ 2.,  6., 10.])  # 数组元素的间隔是一样的
d = np.linspace(1,10,20)
d.size  
# 输出结果: 20

# np.arange() 是“顾首不顾尾”; np.linspace() "顾首且顾尾"

# np.linspace() 的用法:
import matplotlib.pyplot as plt
x = np.linspace(-10,10,10000)
y = x**2

plt.plot(x,y)
# [<matplotlib.lines.Line2D at 0x19089552d30>]

plt.show()


# 方式七:np.eye()  # 创建线性矩阵 (对角线上是1,其他元素为0)
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.]])

"""

np.linspace()用途的 plt.show() 效果图:

array 索引和切片:

ndarray-批量运算:

import numpy as np
a = np.arange(10)
#1. 数组和标量之间的运算:
    a+1   a*3  1//a  a**0.5  a>5
# 2. 同样大小数组之间的运算:
    a+b   a/b  a**b  a%b  a==b  a > b # 最后两个返回bool值

ndarray-索引:

# 一维数组的索引: 
    a[5]
# 多维数组的索引:
    列表式写法: a[2][3]
    新式写法: a[2,3]  # [2,3]  -- 2表示行,3表示列;逗号前是行,逗号后是列

ndarray - 切片:

# 一维数组的切片:
    a[5:8]
    a[4:]
    a[2:10] = 1
# 二维数组的切片:
    a[1:2,3:4]
    a[:,3:5]
    a[:,1]

示例代码:(jupyter notebook)

# array索引和切片

# ndarray--索引:
import numpy as np

# 快速生成一个二维数组的方法:
np.arange(15).reshape((3,5))  # reshape() 里面放一个元组(a,b),a表示行数,b表示列数;.reshape()即将 原数组变成 a行 b列 的多维数组 
"""
# 输出结果:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
"""

a = np.arange(15).reshape((3,5))

# 索引一:
a[1][2]   # 第一行 第三列 (行和列都是从0开始)
# 输出结果: 7
# 索引二:(对于二维数组);主要用这个 
a[1,2]  # [1,2] --- 1 表示行, 2表示列
# 输出结果: 7

# ndarray - 切片
# 1. 一维数组的切片:
np.arange(15)
# 输出结果: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

b = np.arange(15)
b[0:4]  # 也是 “顾首不顾尾”
# 输出结果: array([0, 1, 2, 3])
b[:5]
# array([0, 1, 2, 3, 4])
b[5:]
# array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

# 数组 和 列表 的不同:
c = list(range(15)) # 列表
c 
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

d = b[0:4]  # 数组
d 
# array([0, 1, 2, 3])

e = c[0:4]  # 列表
e
# [0, 1, 2, 3]
d[0] = 20  # 数组:此时会修改原数组 b 的值
b
# array([20,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

e[0] = 20  # 列表 : 此时不会修改原列表的值
c
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] 

# copy() 方法可以创建数组的深拷贝
f = b[0:4].copy()
f
# array([20,  1,  2,  3])

f[0] = 30  # 通过 copy()方法 ,此时就不会修改原数组的值
b 
# array([20,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])


# 二级数组的切片:
bia = np.arange(15).reshape((3,5))
bia
"""
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
"""
# 切出 0,1,5,6 这四个值

# 错误写法:
bia[0:2][0:2]
"""
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
"""
"""
# 错误分析:
bia[0:2] 切出的结果如下:
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
因为 bia[0:2] 默认是按行切,即 从第0行 切到 第1行
此时 bia[0:2] 继续如果继续按照 [0:2] 切,那么得到的依然是原数组(因为还是继续按行切)
"""

# 正确写法:
bia[0:2,0:2]  # [,] 逗号前面是行切,逗号后面是列切
"""
array([[0, 1],
       [5, 6]])
"""

# 切 7,8,12,13 这四个数
bia[1:3,2:4]
"""
array([[ 7,  8],
       [12, 13]])
"""
bia[1:,2:4]  # 另一种写法
"""
array([[ 7,  8],
       [12, 13]])
"""

"""
数组切片与列表的不同:数组切片时并不会自动复制(而是创建一个视图),在切片数组上的修改会影响原数组
.copy() 方法可以创建数组的深拷贝
"""

array 布尔型索引:

# 问题:给一个数组,选出数组中所有大于5的数
a[a>5]

#原理:
1. 数组与标量的运算: a>5 会对a中的每一个元素进行判断,返回一个布尔数组
2. 布尔型索引: 将同样大小的布尔数组传进索引,会返回一个由所有True对应位置的元素的数组 

示例代码:

# ndarray 布尔型索引
# 问题1:给一个数组,选出数组中所有大于5的数
import numpy as np
import random

a = [random.randint(0,10) for i in range(20)]
a = np.array(a)
a[a>5]
# array([ 8,  9,  6,  7,  8,  8,  8,  7,  6,  7, 10])
"""
a[a>5] 的过程分析: 
第一步是 a>5 返回一组 布尔值 (即 数组和标量做运算);
第二步是 a[] 中放一个 布尔型的 列表 或者 数组,且这个列表(或数组)的长度和 a 相同,则 a[] 会将所有为 True 的元素过滤出来返回
"""
a = np.arange(4)
a
# array([0, 1, 2, 3])
a[[True,False,False,True]]
# array([0, 3])

# 问题二:给一个数组,选出数组中所有大于5的偶数
b = [random.randint(0,10) for i in range(20)]
b = np.array(b)
# 方式一:
c = b[b>5]
c[c%2==0]
# array([ 6, 10, 10,  8])

# 错误写法:
# b[b>5][b%2==0]  # 这种写法会报错,因为 [b%2==0] 的长度是 b 的长度, 而 b[b>5] 是一个新的数组,长度已经不再是 b 的长度,所以长度不一致

# 方式二:两个条件写到一个 [] 中
b[(b>5) & (b%2==0)]  # 用 & 连接多个条件,并且由于位运算符的优先级,每个条件要加上 () ;此处的 & 不能换成 and ,换成 and 会报错;& 表示 与,| 表示 或,~ 表示 非
b[(b>5)| (b%2==0)]

array -- 花式索引:

# 问题1:对于一个数组,选出其第1,3,4,6,7 个元素,组成新的二维数组 
a[[1,3,4,6,7]]
# 问题2:对于一个二维数组,选出其第一列和第三列,组成新的二维数组
a[:,[1,3]]

示例代码:

# ndarray - 花式索引
# 问题1:对于一个数组,选出其第1,3,4,6,7 个元素,组成新的二维数组 
import numpy as np

a = np.arange(20)
# 错误写法:
# a[1,3,4,6,7]  # 逗号 分的是 行和列
# 正确写法:(对于一维数组)
a[[1,3,4,6,7]]  # a[] 中 放一个列表,列表中放索引值
# array([1, 3, 4, 6, 7])

# 对于二维数组:
b = np.arange(20).reshape(4,5)
b
"""
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
"""

# 普通索引、切片、布尔索引、花式索引,想要行列搭配,就用 中间一个 逗号,逗号左右用哪种都可以
b[0,2:4]  # 左边用常规索引,表示第0行,右边用切片
# array([2, 3])

b[0,b[0]>2]  # 逗号左边是普通索引,右边是布尔索引
# array([3, 4])
b[0:2,b[0]>2]  # b[0]>2 返回的是 布尔型数组:array([False, False, False,  True,  True])
"""
array([[3, 4],
       [8, 9]])
"""

# 注意:花式索引 和 花式索引 不能同时出现在 逗号 两边,如下:想选取 b 中的 6,8,16,18
b[[1,3],[1,3]]  # 不要用这种写法
# array([ 6, 18])  # 逗号两个都是花式索引时,不会得到自己想要的结果

# 选取 b 中的 6,8,16,18:分步去取
b[[1,3],:][:,[1,3]]  # [[1,3],:] -- 行上取1和3行,列上全取;[:,[1,3]] 列上取1和3列,行上全取
"""
array([[ 6,  8],
       [16, 18]])
"""

NumPy -- 通用函数:

通用函数: 能同时对数组中所有元素进行运算的函数
常见通用函数:

1. 一元函数: abc ,sqrt ,exp ,log ,ceil ,floor ,rint ,trunc ,modf ,isnan ,isinf ,cos ,sin ,tan
2. 二元函数: add ,substract ,multiply ,divide ,power ,mod ,maximum ,minimum 

示例代码:

# 通用函数
import numpy as np
a = np.arange(-5,5)
a
# array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

abs(a)  # python 内置的 abs 也能对数组进行绝对值操作
# 输出结果: array([5, 4, 3, 2, 1, 0, 1, 2, 3, 4])

np.abs(a)  # 对数组中的每个元素进行绝对值操作
# array([5, 4, 3, 2, 1, 0, 1, 2, 3, 4])  

np.sqrt(a)  # 对数组中的每个元素进行 开方(二次方) 运算
"""
array([       nan,        nan,        nan,        nan,        nan,
       0.        , 1.        , 1.41421356, 1.73205081, 2.        ])
"""

# 小数变整数的方法:
# 1. int 方法: 向 0 取整法(向0的方法取整)
b = 1.6
int(b)
# 输出结果: 1

c = -1.6
int(c)
# 输出结果: -1

# 2. round 方法: 四舍五入 ;小数位的值小于 0.5时,向0取整,小数位的值大于等于0.5时 向 0 的反方向取整
round(b)
# 输出结果: 2

round(c)
# 输出 结果: -2

import math

# 3. 向上取整
# 3.1 . math.ceil()
math.ceil(b)
# 2
math.ceil(c)
# -1

# 4. 向下取整
# 4.1 . math.floor() 
math.floor(b)
# 输出结果: 1
math.floor(c)
# -2 

d = np.arange(-5.5,5.5)
d
# array([-5.5, -4.5, -3.5, -2.5, -1.5, -0.5,  0.5,  1.5,  2.5,  3.5,  4.5])

# 数组的取整:

# 1. np.floor(数组) : 对数组中的所有元素进行 向下取整
np.floor(d)
# array([-6., -5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])

# 2. np.ceil(数组) : 对数组中的所有元素进行 向上取整
np.ceil(d)
# array([-5., -4., -3., -2., -1., -0.,  1.,  2.,  3.,  4.,  5.])

# 3. np.round(数组) : 对数组中的元素进行 四舍五入
np.round(d)
# array([-6., -4., -4., -2., -2., -0.,  0.,  2.,  2.,  4.,  4.])

"""
在实际使用中发现round函数并不总是如上所说的四舍五入。可参考以下链接:
http://www.runoob.com/python/func-number-round.html
http://www.runoob.com/w3cnote/python-round-func-note.html
"""

# 4. np.rint(数组) : 作用和 np.round() 一样
np.rint(d)
# array([-6., -4., -4., -2., -2., -0.,  0.,  2.,  2.,  4.,  4.])
# 5. np.trunc(数组) : 对数组中的每个数值进行 向0取整
np.trunc(d)
# array([-5., -4., -3., -2., -1., -0.,  0.,  1.,  2.,  3.,  4.])

# np.modf(数组) : 返回两个数组, 一个数组中是 小数 部分,一个数组中是 整数 部分
np.modf(d)
"""
(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.]))
"""
x,y = np.modf(d)  # 可用元组、列表的方式接收
x
# 输出结果: array([-0.5, -0.5, -0.5, -0.5, -0.5, -0.5,  0.5,  0.5,  0.5,  0.5,  0.5])
y
# 输出结果: array([-5., -4., -3., -2., -1., -0.,  0.,  1.,  2.,  3.,  4.])


# 数组的 inf
e = np.arange(0,5)
e
# array([0, 1, 2, 3, 4])

5/e
# array([       inf, 5.        , 2.5       , 1.66666667, 1.25      ])

# 数组的 nan
np.sqrt(d)
"""
array([       nan,        nan,        nan,        nan,        nan,
              nan, 0.70710678, 1.22474487, 1.58113883, 1.87082869,
       2.12132034])
"""

"""
补充: 浮点数特殊值
1. nan (not a number):不等于任何浮点数(nan != nan)
2. inf (infinity):比任何浮点数都大
3. NumPy 中创建特殊值:np.nan 和  np.inf
4. 在数据分析中, nan 常被用作表示数据缺失值
"""

# float("amaosi")  # 对这种字符串进行 float() 会报错
float("nan")  # 对字符串 "nan" 进行 float 则不会报错
# 输出结果: nan
float("inf")
# 输出结果: inf

e/e
# 输出结果: array([nan,  1.,  1.,  1.,  1.])

np.nan
# 输出结果: nan

np.nan == np.nan
# 输出结果: False

np.nan is np.nan
# 输出结果: True

f = e/e
f
# 输出结果: array([nan,  1.,  1.,  1.,  1.])

# 判断 f 中是否有 nan

f == np.nan
# 输出结果: array([False, False, False, False, False])
# 所以不能用类似布尔型索引判断 f 中是否有 nan

f is np.nan
# 输出结果: False  # 这种方式也不行

np.nan in f
# 输出结果: False

# 正确方法: np.isnan(数组) 方法: 返回数组中是否有 nan ; ** 该方法很重要,用于缺失值处理
np.isnan(f)
# 输出结果: array([ True, False, False, False, False])

# 用法: 去掉 f 中的 nan
f[~np.isnan(f)]  # ~ 表示“非”; & 表示“与”, | 表示“或”
# 输出结果: array([1., 1., 1., 1.])  

# inf 的相关:
float("inf") > 10000000000000000000000000000000
# 输出结果: True

# 去掉数组中的 inf :
m = np.array([1,2,3,4,5])
n = np.array([1,0,1,0,1])
k = m/n
k 
# 输出结果: array([ 1., inf,  3., inf,  5.])

# 方式一:
k[k!=np.inf]
# 输出结果: array([1., 3., 5.])
# 方式二:
k[~np.isinf(k)]
# 输出结果: array([1., 3., 5.])

# 二元函数:能放两个数组
# np.maximum(数组1,数组2)  # 返回较大的数
m = np.array([6,2,8,9,7])
n = np.array([4,5,3,10,5])
np.maximum(m,n)
# 输出结果: array([ 6,  5,  8, 10,  7])

numpy -- 统计方法和随机数生成:

1. 数学和统计方法:

sum   # 求和
mean  # 求平均数
std  # 求标准差
var  # 求方差
min  # 求最小值
max  # 求最大值
argmin  # 求最小值的索引
argmax  # 求最大值的索引    

2. NumPy随机数生成:

rand  # 给定形状产生随机数组(0到1之间的数)
randint  # 给定形状产生随机整数
choice # 给定形状产生随机选择
shuffle # 与 random.shuffle 相同
uniform # 给定形状产生随机数组
原文地址:https://www.cnblogs.com/neozheng/p/10416101.html