本篇博客主要记录数据分析中Numpy的相关使用,课件资源来自内蒙古农业大学。所有代码都使用Jupyter Notebook运行,并附上运行结果。
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
# 注意默认都会给numpy包设置别名为np
import numpy as np
通过 NumPy 的内置函数 array() 可以创建 ndarray 对象,其语法格式如下:
numpy.array(object, dtype = None, copy = True, order = None,subok=False,ndmin = 0)
参数说明
序号 | 参数 | 描述说明 |
---|---|---|
1 | object | 表示一个数组序列。 |
2 | dtype | 可选参数,通过它可以更改数组的数据类型。 |
3 | copy | 可选参数,表示数组能否被复制,默认是 True。 |
4 | ndmin | 用于指定数组的维度。 |
5 | subok | 可选参数,类型为bool值,默认False。为True,使用object的内部数据类型;False:使用object数组的数据类型。 |
#array()函数,括号内可以是列表、元祖、数组、迭代对象,生成器等
np.array([1,2,3,4,5])
array([1, 2, 3, 4, 5])
# 元组
np.array((1,2,3,4,5))
array([1, 2, 3, 4, 5])
a = np.array([1,2,3,4,5])
# 数组
np.array(a)
# 迭代对象
np.array(range(10))
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 生成器
np.array([i**2 for i in range(10)])
array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81])
# 列表中元素类型不相同
np.array([1,1.5,3,4.5,'5'])
array(['1', '1.5', '3', '4.5', '5'], dtype='
ar1 = np.array(range(10)) # 整型
ar1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
ar2 = np.array([1,2,3.14,4,5]) # 浮点型
ar2
array([1. , 2. , 3.14, 4. , 5. ])
ar3 = np.array([
[1,2,3],
('a','b','c')
]) # 二维数组:嵌套序列(列表,元祖均可)
ar3
array([['1', '2', '3'],
['a', 'b', 'c']], dtype='
# 注意嵌套序列数量不一会怎么样
ar4 = np.array([[1,2,3],('a','b','c','d')])
ar4
array([list([1, 2, 3]), ('a', 'b', 'c', 'd')], dtype=object)
# 注意嵌套序列数量不一会怎么样
ar4 = np.array([[1,2,3],[1,2,3,4]])
ar4
array([list([1, 2, 3]), list([1, 2, 3, 4])], dtype=object)
a = np.array([1,2,3,4,5])
print(a)
# 设置数组元素类型
has_dtype_a = np.array([1,2,3,4,5],dtype='float')
has_dtype_a
# [1.,2.,3.,4.,5.]
[1 2 3 4 5]
array([1., 2., 3., 4., 5.])
思考如何将浮点型的数据,设置为整形,会是什么情况?
np.array([1.1,2.5,3.8,4,5],dtype='int')
array([1, 2, 3, 4, 5])
a = np.array([1,2,3,4,5])
# 定义b,复制a
b = np.array(a)
# 输出a和b的id
print('a:', id(a), ' b:', id(b))
print('以上看出a和b的内存地址')
# a =--复制
# b ---未复制
b[0] = 10
print(a)
a: 2066732212352 b: 2066732213152
以上看出a和b的内存地址
[1 2 3 4 5]
# 当修改b的元素时,a不会发生变化
b[0] = 10
print('a:', a,' b:', b)
print('='*10)
a: [1 2 3 4 5] b: [10 2 3 4 5]
==========
a = np.array([1,2,3,4,5])
# 定义b,当设置copy参数为Fasle时,不会创建副本,
# 两个变量会指向相同的内容地址,没有创建新的对象
b = np.array(a, copy=False)
# 输出a和b的id
print('a:', id(a), ' b:', id(b))
print('以上看出a和b的内存地址')
# 由于a和b指向的是相同的内存地址,因此当修改b的元素时,a会发生变化
b[0] = 10
print('a:',a,' b:',b)
a: 2066732267520 b: 2066732267520
以上看出a和b的内存地址
a: [10 2 3 4 5] b: [10 2 3 4 5]
a = np.array([1,2,3])
print(a)
a = np.array([1,2,3], ndmin=2)
a
[1 2 3]
array([[[1, 2, 3]]])
4.subok参数,类型为bool值,默认False。为True,使用object的内部数据类型;False:使用object数组的数据类型。
# 创建一个矩阵
a = np.mat([1,2,3,4])
# 输出为矩阵类型
print(type(a))
#既要复制一份副本,又要保持原类型
at = np.array(a,subok=True)
af = np.array(a) # 默认为False
print('at,subok为True:',type(at))
print('af,subok为False:',type(af))
print(id(at),id(a))
at,subok为True:
af,subok为False:
2066738151720 2066738151608
#定义个数组
a = np.array([2,4,3,1])
# 在定义b时,如果想复制a的几种方案:
# 1.使用np.array()
b = np.array(a)
print('b = np.array(a):',id(b),id(a))
# 2.使用数组的copy()方法
c = a.copy()
print('c = a.copy():',id(c),id(a))
# 注意不能直接使用=号复制,直接使用=号,会使2个变量指向相同的内存地址
d = a
# 修改d也会相应的修改a
print('d = a:',id(d),id(a))
b = np.array(a): 2066731363744 2066731901216
c = a.copy(): 2066732267520 2066731901216
d = a: 2066731901216 2066731901216
根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
numpy.arange(start, stop, step, dtype)
参数说明
序号 | 参数 | 描述说明 |
---|---|---|
1 | start | 起始值,默认为0 |
2 | stop | 终止值(不包含) |
3 | step | 步长,默认为1 |
4 | dtype | 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。 |
np.arange(10)
# np.array(range(10))
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 可以使用浮点型数值
np.arange(3.1)
array([0., 1., 2., 3.])
# 这个的结果?
range(3.1)
# a --- [0., 1., 2., 3.]
# b --- [0, 1, 2, 3]
# c --- 错误
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
1 # 这个的结果?
----> 2 range(3.1)
3 # a --- [0., 1., 2., 3.]
4 # b --- [0, 1, 2, 3]
5 # c --- 错误
TypeError: 'float' object cannot be interpreted as an integer
# 返回浮点型的,也可以指定类型
x = np.arange(5, dtype = float)
x
array([0., 1., 2., 3., 4.])
# 起始10 ,终止值20 步长2
np.arange(10,20,2)
array([10, 12, 14, 16, 18])
# 起始0 ,终止值10 步长3
ar2 = np.arange(20,3) # 这个书写是否正确?
print(ar2)
[]
#正确的书写格式是什么
# 起始0 ,终止值10 步长3
ar2 = np.arange(0,20,3) # 这个书写是否正确?
print(ar2)
ar3 = np.arange(20,step=3)
ar3
[ 0 3 6 9 12 15 18]
array([ 0, 3, 6, 9, 12, 15, 18])
# 如果数组太大而无法打印,NumPy会自动跳过数组的中心部分,并只打印边角:
np.arange(10000)
array([ 0, 1, 2, ..., 9997, 9998, 9999])
在庆祝教师节活动中,学校为了烘托节日气氛,在200米长的校园主干道一侧,
从起点开始,每间隔3米插一面彩旗,由近到远排成一排,
问:1.最后一面彩旗会插到终点处吗?
2.一共应插多少面彩旗?
# 1最后一面彩旗会插到终点处吗?
np.arange(0,200+1,3)
len(np.arange(0,200+1,3))
67
如何防止 float 不精确影响numpy.arange
注意:ceil((stop - start)/step)确定项目数,小浮点不精确(stop = .400000001)可以向列表中添加意外值。
想得到一个长度为3的、从0.1开始的、间隔为0.1的数组,想当然地如下coding,结果意料之外:
np.arange(0.1,0.4,0.1)
array([0.1, 0.2, 0.3, 0.4])
返回在间隔[开始,停止]上计算的num个均匀间隔的样本。数组是一个等差数列构成
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数说明
序号 | 参数 | 描述说明 |
---|---|---|
1 | start | 必填项,序列的起始值, |
2 | stop | 必填项,序列的终止值,如果endpoint为true,该值包含于数列中 |
3 | num | 要生成的等步长的样本数量,默认为50 |
4 | endpoint | 该值为 true 时,数列中包含stop值,反之不包含,默认是True。 |
5 | retstep | 如果为 True 时,生成的数组中会显示间距,反之不显示。 |
6 | dtype | ndarray 的数据类型 |
# 以下实例用到三个参数,设置起始点为 1 ,终止点为 10,数列个数为 10。
a = np.linspace(1,10,10)
a
array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
a = np.linspace(1,10,endpoint=False)
a
array([1. , 1.18, 1.36, 1.54, 1.72, 1.9 , 2.08, 2.26, 2.44, 2.62, 2.8 ,
2.98, 3.16, 3.34, 3.52, 3.7 , 3.88, 4.06, 4.24, 4.42, 4.6 , 4.78,
4.96, 5.14, 5.32, 5.5 , 5.68, 5.86, 6.04, 6.22, 6.4 , 6.58, 6.76,
6.94, 7.12, 7.3 , 7.48, 7.66, 7.84, 8.02, 8.2 , 8.38, 8.56, 8.74,
8.92, 9.1 , 9.28, 9.46, 9.64, 9.82])
# 使用等差数列 实现输出0 0.5 1 1.5 2 2.5 3 3.5 4
# 选择题: A 还是 B
A = np.linspace(0, 4, 9)
print(A)
B = np.linspace(0, 4.1, 9)
print(B)
[0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. ]
[0. 0.5125 1.025 1.5375 2.05 2.5625 3.075 3.5875 4.1 ]
# 一下实例用到三个参数,设置起始位置为2.0,终点为3,0 数列个数为5
ar1 = np.linspace(2.0, 3.0, num=5)
ar1
array([2. , 2.25, 2.5 , 2.75, 3. ])
# 设置参数endpoint 为False时,不包含终止值
ar1 = np.linspace(2.0, 3.0, num=5, endpoint=False)
ar1
array([2. , 2.2, 2.4, 2.6, 2.8])
#设置retstep显示计算后的步长
ar1 = np.linspace(2.0,3.0,num=5, retstep=True)
print(ar1)
type(ar1)
(array([2. , 2.25, 2.5 , 2.75, 3. ]), 0.25)
tuple
设置retstep显示计算后的步长
ar1 = np.linspace(2.0,3.0,num=5,endpoint=False,retstep=True)
ar1
```python
#想得到一个长度为10的、从0.1开始的、间隔为0.1的数组
np.linspace(0.1,1,10)
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
等差数列 在线性回归经常作为样本集
如:生成x_data,值为[0, 100]之间500个等差数列数据集合作为样本特征,根据目标线性方程y=3*x+2,生成相应的标签集合y_data
x_data = np.linspace(0,100,500)
x_data
返回在间隔[开始,停止]上计算的num个均匀间隔的样本。数组是一个等比数列构成
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数说明
序号 | 参数 | 描述说明 |
---|---|---|
1 | start | 必填项,序列的起始值, |
2 | stop | 必填项,序列的终止值,如果endpoint为true,该值包含于数列中 |
3 | num | 要生成的等步长的样本数量,默认为50 |
4 | endpoint | 该值为 true 时,数列中包含stop值,反之不包含,默认是True。 |
5 | base | 对数 log 的底数 |
6 | dtype | ndarray 的数据类型 |
a = np.logspace(0,9,10,base=2)
a
array([ 1., 2., 4., 8., 16., 32., 64., 128., 256., 512.])
np.logspace(A,B,C,base=D)
# 我们先使用前3个参数,将[1,5]均匀分成3个数,得到{1,3,5},
# 然后利用第4个参数base=2(默认是10)使用指数函数可以得到最终输出结果 {2^1,2^3,2^5}
np.logspace(1,5,3,base=2)
array([ 2., 8., 32.])
# 取得1到2之间10个常用对数
np.logspace(1.0,2.0,num=10)
array([ 10. , 12.91549665, 16.68100537, 21.5443469 ,
27.82559402, 35.93813664, 46.41588834, 59.94842503,
77.42636827, 100. ])
a = np.linspace(1.0,2.0,num=10)
print(a)
10 ** a
[1. 1.11111111 1.22222222 1.33333333 1.44444444 1.55555556
1.66666667 1.77777778 1.88888889 2. ]
array([ 10. , 12.91549665, 16.68100537, 21.5443469 ,
27.82559402, 35.93813664, 46.41588834, 59.94842503,
77.42636827, 100. ])
创建指定大小的数组,数组元素以 0 来填充
numpy.zeros(shape, dtype = float, order = ‘C’)
参数说明
序号 | 参数 | 描述说明 |
---|---|---|
1 | shape | 数组形状 |
2 | dtype | 数据类型,可选 |
# 默认为浮点数
np.zeros(5)
array([0., 0., 0., 0., 0.])
# 设置为整形
np.zeros((5,), dtype = 'int')
array([0, 0, 0, 0, 0])
# 2行2列的全0数组
np.zeros((2,2))
array([[0., 0.],
[0., 0.]])
#zeros_like返回具有与给定数组相同的形状和类型的零数组
ar1 = np.array([[1,2,3],[4,5,6]])
np.zeros_like(ar1)
array([[0, 0, 0],
[0, 0, 0]])
# 全为1的数列
ar5 = np.ones(9)
ar6 = np.ones((2,3,4))
ar7 = np.ones_like(ar3)
print('ar5:',ar5)
print('ar6:',ar6)
print('ar7:',ar7)
ar5: [1. 1. 1. 1. 1. 1. 1. 1. 1.]
ar6: [[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]]
ar7: [1 1 1 1 1 1 1]
NumPy 的数组中比较重要 ndarray 对象属性有:
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
返回一个包含数组维度的元组,对于矩阵,n 行 m 列,它也可以用于调整数组维度
import numpy as np
a = np.array([1,2,3,4,5,6])
a.shape
(6,)
b = np.array([[1,2,3],[4,5,6]])
b.shape
(2, 3)
c = np.array([
[
[1,2,3],
[4,5,6]
],
[
[7,8,9],
[10,11,12]
]
])
c.shape
(2, 2, 3)
返回调整维度后的副本,而不改变原 ndarray。
a = np.arange(20).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 = np.array([
[0,1],
[2,3]
])
b_2_3 = np.resize(a, (2,10))
b_2_3
array([[0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
[2, 3, 0, 1, 2, 3, 0, 1, 2, 3]])
返回数组的维度(秩):轴的数量,或者维度的数量,是一个标量,一维数组的秩为 1,二维数组的秩为 2
a = np.array([1,2,3,4,5,6])
b = a.reshape(2,3)
c = np.array([
[
[1, 2, 3],
[4, 5, 6]
],
[
[11, 22, 33],
[44, 55, 66]
]
])
print('a的ndim:',a.ndim)
print('b的ndim:', b.ndim)
print('c的ndim:', c.ndim)
a的ndim: 1
b的ndim: 2
c的ndim: 3
数组元素的总个数,相当于 .shape 中 n*m 的值
a = np.array([1,2,3,4,5,6])
print('[1,2,3,4,5,6]的size:', a.size)
a = np.array([[1,2,3],[4,5,6]])
print('[[1,2,3],[4,5,6]]的size:', a.size)
[1,2,3,4,5,6]的size: 6
[[1,2,3],[4,5,6]]的size: 6
ndarray 对象的元素类型
a = np.array([1,2,3,4,5,6])
print(a.dtype)
b = np.array([1.1,2,3,4,5,6])
print(b.dtype)
int32
float64
numpy数据类型转换,调用astype返回数据类型修改后的数据,但是源数据的类型不会变
a = np.array([1.1,1.2])
print('a的数据类型:', a.dtype)
print('astype修改数据类型:',a.astype('float32').dtype)
print('原数据类型未改变',a.dtype)
# 正确操作
a = a.astype('float32')
print('修改类型后再次操作,类型改变:',a.dtype)
a的数据类型: float64
astype修改数据类型: float32
原数据类型未改变 float64
修改类型后再次操作,类型改变: float32
以字节的形式返回数组中每一个元素的大小。
例如,一个元素类型为 float64 的数组 itemsize 属性值为 8(float64 占用 64 个 bits,每个字节长度为 8,所以 64/8,占用 8 个字节)
a = np.array([1.1,2.2,3.3])
print('dtype:',a.dtype,' itemsize:',a.itemsize)
b = np.array([1,2,3,4,5])
print('dtype:',b.dtype,' itemsize:',b.itemsize)
dtype: float64 itemsize: 8
dtype: int32 itemsize: 4
名称 | 描述 | 名称 | 描述 |
---|---|---|---|
bool_ | 布尔型数据类型(True 或者 False) | float_ | float64 类型的简写 |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) | float16/32/64 | 半精度浮点数:1 个符号位,5 个指数位,10个尾数位 单精度浮点数:1 个符号位,8 个指数位,23个尾数位 双精度浮点数,包括:1 个符号位,11 个指数位,52个尾数位 |
intc | 和 C 语言的 int 类型一样,一般是 int32 或 int 64 | complex_ | 复数类型,与 complex128 类型相同 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,通常为 int32 或 int64) | complex64/128 | 复数,表示双 32 位浮点数(实数部分和虚数部分) 复数,表示双 64 位浮点数(实数部分和虚数部分) |
int8/16/32/64 | 代表与1字节相同的8位整数 代表与2字节相同的16位整数 代表与4字节相同的32位整数 代表与8字节相同的64位整数 |
str_ | 表示字符串类型 |
uint8/16/32/64 | 代表1字节(8位)无符号整数 代表与2字节相同的16位整数 代表与4字节相同的32位整数 代表与8字节相同的64位整数 |
string_ | 表示字节串类型,也就是bytes类型 |
# 将数组中的类型存储为浮点型
a = np.array([1,2,3,4],dtype=np.float64)
a
array([1., 2., 3., 4.])
# 将数组中的类型存储为布尔类型
a = np.array([0,1,2,3,4],dtype=np.bool_)
print(a)
a = np.array([0,1,2,3,4],dtype=np.float_)
print(a)
[False True True True True]
[0. 1. 2. 3. 4.]
# str_和string_区别
str1 = np.array([1,2,3,4,5,6],dtype=np.str_)
string1 = np.array([1,2,3,4,5,6],dtype=np.string_)
str2 = np.array(['我们',2,3,4,5,6],dtype=np.str_)
str3 = np.array(str1)
print(str1,str1.dtype)
print(string1,string1.dtype)
print(str2,str2.dtype)
print(str3,str3.dtype)
['1' '2' '3' '4' '5' '6']
在内存里统一使用unicode, 记录到硬盘或者编辑文本的时候都转换成了utf8
UTF-8 将Unicode编码后的字符串保存到硬盘的一种压缩编码方式
使用数据类型标识码
字符 | 对应类型 | 字符 | 对应类型 | 字符 | 对应类型 | 字符 | 对应类型 |
---|---|---|---|---|---|---|---|
b | 代表布尔型 | i | 带符号整型 | u | 无符号整型 | f | 浮点型 |
c | 复数浮点型 | m | 时间间隔(timedelta) | M | datatime(日期时间) | O | Python对象 |
S,a | 字节串(S)与字符串(a) | U | Unicode | V | 原始数据(void) |
还可以将两个字符作为参数传给数据类型的构造函数。此时,第一个字符表示数据类型,
第二个字符表示该类型在内存中占用的字节数(2、4、8分别代表精度为16、32、64位的
浮点数):
# 首先创建结构化数据类型
dt = np.dtype([('age', 'i1')])
print(dt)
student = np.array([18,19],dtype=dt)
print(student,student.dtype,student.ndim)
print(student['age'])
[('age', 'i1')]
[(18,) (19,)] [('age', 'i1')] 1
[18 19]
以下示例描述一位老师的姓名、年龄、工资的特征,该结构化数据其包含以下字段:
str 字段:name
int 字段:age
float 字段:salary
teacher = np.dtype([('name', np.str_, 2), ('age', 'i1'),('salary','f4')])
print(teacher)
b = np.array([('wl',32,12345.6),('wzh',20,23456.7)],dtype=teacher)
print(b,b.dtype,b.ndim)
[('name', '
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。
ndarray 数组可以基于 0 - n 的下标进行索引
区别在于:数组切片是原始数组视图(这就意味着,如果做任何修改,原始都会跟着更改)。
这也意味着,如果不想更改原始数组,我们需要进行显式的复制,从而得到它的副本(.copy())。
冒号分隔切片参数 [start:stop:step]
ar1 = np.arange(10)
ar1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
ar2 = ar1[2:7:2]
ar2
array([2, 4, 6])
冒号 : 的解释:如果只放置一个参数,
print('ar1:',ar1)
# 返回索引对应的数据,(注意是从0开始的)
print('ar1[4]:',ar1[4])
ar1: [0 1 2 3 4 5 6 7 8 9]
ar1[4]: 4
ar3 = np.arange(1,20,2)
ar3
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
从该索引开始以后的所有项都将被提取
print(ar3)
# 从索引2开始,取后面所有数据
ar3[2:]
[ 1 3 5 7 9 11 13 15 17 19]
array([ 5, 7, 9, 11, 13, 15, 17, 19])
从索引开始,到索引结束(不包含结束)
print(ar3)
# 从索引2开始到索引7(包含索引7)
print(ar3[2:7])
print(ar3[:-2])
[ 1 3 5 7 9 11 13 15 17 19]
[ 5 7 9 11 13]
[ 1 3 5 7 9 11 13 15]
# 取所有数据,步长-1,
ar3[::-1]
array([19, 17, 15, 13, 11, 9, 7, 5, 3, 1])
print(ar3[:-2:2])
print(ar3[1:-2:2])
print(ar3[1:-3:2])
print(ar3[:6])
print(ar3[6:])
[ 1 5 9 13]
[ 3 7 11 15]
[ 3 7 11]
[ 1 3 5 7 9 11]
[13 15 17 19]
为什么切片和区间会忽略最后一个元素
计算机科学家edsger w.dijkstra(艾兹格·W·迪科斯彻),delattr这一风格的解释应该是比较好的:
比如
ar = np.array([10,20,30,40,50,60])
# 在下标2的地方开始分割
print('ar[2:]',ar[2:])
# 在下标3的之前结束分割
print('ar[:3]',ar[:3])
# 使用下标2将数组分别为不重叠的两部分
print('ar[:2]',ar[:2])
print('ar[2:]',ar[2:])
ar[2:] [30 40 50 60]
ar[:3] [10 20 30]
ar[:2] [10 20]
ar[2:] [30 40 50 60]
同样适用上述索引提取方法:
# 定义4行5列的数据
ar4_5 = np.arange(20).reshape(4,5)
ar4_5
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
# 返回ar4_5的秩(几维)
ar4_5.ndim
2
# 切片为下一维度的一个元素,所以是一维数组
ar4_5[2]
array([10, 11, 12, 13, 14])
# 二次索引取得,一维数组中的元素
ar4_5[2][2]
12
ar4_5[2:]
array([[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
# 获取第一行元素
s = ar4_5[:][0]
s
array([0, 1, 2, 3, 4])
注意:切片还可以使用省略号“…”,如果在行位置使用省略号,那么返回值将包含所有行元素,反之,则包含所有列元素。
需要取得第二列数据
print(ar4_5[...,1])
[ 1 6 11 16]
#返回第二列后的所有项
ar4_5[...,1:]
array([[ 1, 2, 3, 4],
[ 6, 7, 8, 9],
[11, 12, 13, 14],
[16, 17, 18, 19]])
ar4_5[2]
array([10, 11, 12, 13, 14])
在 NumPy 中还可以使用高级索引方式,比如整数数组索引、布尔索引,以下将对两种种索引方式做详细介绍。
#创建二维数组
x = np.array([
[1,2,1,1],
[3,4,1,2],
[5,6,2,3]
])
#[0,1,2]代表行索引;[0,1,0]代表列索引
y = x[
[0,1,2],[0,1,0]
]
# y分别获取x中的(0,0)、(1,1) 和(2,0)的数据
print(y)
x[
[0,1,2],:
]
[1 4 5]
array([[1, 2, 1, 1],
[3, 4, 1, 2],
[5, 6, 2, 3]])
b = np.array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9,10,11]])
a = b[[0,0,3,3],[0,2,0,2]]
print(a)
r = np.array([[0,0] ,[3,3]]).reshape(4)
l = np.array([[0,2] ,[0,2]]).reshape(4)
print(r)
print(l)
s = b[r,l].reshape(2,2)
print(s)
[ 0 2 9 11]
[0 0 3 3]
[0 2 0 2]
[[ 0 2]
[ 9 11]]
a = np.array([
[1,2,3],
[4,5,6],
[7,8,9]
])
# 行取得2行和3行,列取得2列和3列
b = a[1:3, 1:3]
b
array([[5, 6],
[8, 9]])
当输出的结果需要经过布尔运算(如比较运算)时,此时会使用到另一种高级索引方式,即布尔数组索引。下面示例返回数组中大于 6 的的所有元素:
# #返回所有大于6的数字组成的数组
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(x)
print(x.shape)
x[x>6]
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
(4, 3)
array([ 7, 8, 9, 10, 11])
(注意:一维数组的长度必须和想要切片的维度或轴的长度一致)。
提取出数组中所有奇数
修改奇数值修改为-1
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
# 答案:
x[x%2 == 1]
array([ 1, 3, 5, 7, 9, 11])
x[x%2 == 1] = -1
x
array([[ 0, -1, 2],
[-1, 4, -1],
[ 6, -1, 8],
[-1, 10, -1]])
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
# 以上x中大于4并且小于9的数据
x[(x>4) & (x<9)]
array([5, 6, 7, 8])
# 创建3*4的数组
a3_4 = np.arange(12).reshape((3,4))
a3_4
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 行变量 存在3个元素
row1 = np.array([False,True,True])
# 列变量 存在4个元素
column1 = np.array([True,False,True,False])
# a3_4 是3行, 做切片时也提供3个元素的数组,轴的长度一致
a3_4[row1]
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
a3_4[:,column1]
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
那么是否可以用两个一维布尔数组进行切片呢?我们继续进行试验得到如下结果:
a3_4[row1,column1]
array([ 4, 10])
从结果上看,它实际上等价于下面的代码。
a3_4[[1, 2],[0, 2]]
array([ 4, 10])
NumPy 能方便地求出统计学常见的描述性统计量。
又称中点数,中值
是按顺序排列的一组数据中居于中间位置的数,代表一个样本、种群或概率分布中的一个数值
ar1 = np.array([1,3,5,6,8])
np.median(ar1)
5.0
ar1 = np.array([1,3,5,6,8,9])
np.median(ar1)
5.5
m1 = np.arange(20).reshape((4,5))
print(m1)
# 默认求出数组所有元素的平均值
m1.mean()
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
9.5
若想求某一维度的平均值,设置 axis 参数,多维数组的元素指定
m1 = np.arange(20).reshape((4,5))
print(m1)
# axis=0将从上往下计算平均值
m1.mean(axis=0)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
array([ 7.5, 8.5, 9.5, 10.5, 11.5])
# axis=1 将从左往右计算平均值
m1.mean(axis=1)
array([ 2., 7., 12., 17.])
在概率统计中最常使用作为统计分布程度上的测量,是反映一组数据离散程度最常用的一种量化形式,是表示精确度的重要指标
简单来说,标准差是一组数据平均值分散程度的一种度量。
'''
例如,A、B两组各有6位学生参加同一次语文测验,
A组的分数为95、85、75、65、55、45,
B组的分数为73、72、71、69、68、67。
分析那组学生之间的差距大?
'''
a = np.array([95,85,75,65,55,45])
b = np.array([73,72,71,69,68,67])
print('A组的标准差为:',a.std())
print('B组的标准差为:',b.std())
A组的标准差为: 17.07825127659933
B组的标准差为: 2.160246899469287
标准差应用于投资上,可作为量度回报稳定性的指标。标准差数值越大,代表回报远离过去平均数值,回报较不稳定故风险越高。相反,标准差数值越小,代表回报较为稳定,风险亦较小。
衡量随机变量或一组数据时离散程度的度量
a = np.array([95,85,75,65,55,45])
b = np.array([73,72,71,69,68,67])
print('A组的方差为:',a.var())
print('B组的方准差为:',b.var())
A组的方差为: 291.6666666666667
B组的方准差为: 4.666666666666667
print(m1)
print(m1.max())
print('axis=0,从上往下查找:',m1.max(axis=0))
print('axis=1,从左往右查找',m1.max(axis=1))
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
19
axis=0,从上往下查找: [15 16 17 18 19]
axis=1,从左往右查找 [ 4 9 14 19]
print(m1)
print(m1.min())
print('axis=0,从上往下查找:',m1.min(axis=0))
print('axis=1,从左往右查找',m1.min(axis=1))
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
0
axis=0,从上往下查找: [0 1 2 3 4]
axis=1,从左往右查找 [ 0 5 10 15]
print(m1)
print(m1.sum())
print('axis=0,从上往下查找:',m1.sum(axis=0))
print('axis=1,从左往右查找',m1.sum(axis=1))
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
190
axis=0,从上往下查找: [30 34 38 42 46]
axis=1,从左往右查找 [10 35 60 85]
即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数
numpy.average(a, axis=None, weights=None, returned=False)
weights: 数组,可选
与 a 中的值关联的权重数组。 a 中的每个值都根据其关联的权重对平均值做出贡献。权重数组可以是一维的(在这种情况下,它的长度必须是沿给定轴的 a 的大小)或与 a 具有相同的形状。如果 weights=None,则假定 a 中的所有数据的权重等于 1。一维计算是:
avg = sum(a * weights) / sum(weights)
对权重的唯一限制是 sum(weights) 不能为 0。
average_a1 = [20,30,50]
print(np.average(average_a1))
print(np.mean(average_a1))
33.333333333333336
33.333333333333336
使用“示例—权重已知”中的数据,我们对比两位学生的考试成绩
姓名 | 平时测验 | 期中考试 | 期末考试 |
---|---|---|---|
小明 | 80 | 90 | 95 |
小刚 | 95 | 90 | 80 |
学校规定的学科综合成绩的计算方式是:
平时测验占比 | 期中考试占比 | 期末考试占比 |
---|---|---|
20% | 30% | 50% |
要求 :比较谁的综合成绩更好
xiaoming = np.array([80,90,95])
xiaogang = np.array([95,90,80])
# 权重:
weights = np.array([0.2,0.3,0.5])
print("小明的综合成绩:", np.average(xiaoming,weights=weights))
print("小刚的综合成绩:", np.average(xiaogang,weights=weights))
小明的综合成绩: 90.5
小刚的综合成绩: 86.0
NumPy中也有自己的随机函数,包含在random模块中。它能产生特定分布的随机数,如正态分布等。接下来介绍一些常用的随机数。
函数名 | 功能 | 参数使用(int a,b,c,d) |
---|---|---|
rand(int1,[int2,[int3,]]) | 生成(0,1)均匀分布随机数 | (a),(a,b),(a,b,c) |
randn(int1,[int2,[int3,]]) | 生成标准正态分布随机数 | (a),(a,b),(a,b,c) |
randint(low[,hight,size,dtype]) | 生成随机整数 | (a,b),(a,b,c),(a,b,(c,d)) |
sample(size) | 生成[0,1)随机数 | (a),((a,b)),((a,b,c)) |
# 创建4行2列的随机数据
np.random.rand(4,2)
array([[0.10307354, 0.88449025],
[0.32310711, 0.28757325],
[0.33313168, 0.88716388],
[0.97295466, 0.38672369]])
# 创建2块2行3列的随机数据
np.random.rand(2,2,3)
array([[[0.97412138, 0.69357386, 0.51862264],
[0.7903512 , 0.45968668, 0.25284011]],
[[0.6030978 , 0.56302697, 0.78413352],
[0.71285203, 0.78016447, 0.68863626]]])
标准正态分布又称为u分布,是以0为均值、以1为标准差的正态分布,记为N(0,1)。
from matplotlib import pyplot as plt
a = np.random.randn(10)
print(a)
# 直方图
plt.hist(a)
[-0.00818692 1.76004047 -0.40911067 1.62238285 -0.05143092 0.05107557
-0.31098123 2.36486525 -0.03008396 0.49025143]
(array([2., 4., 0., 1., 0., 0., 0., 2., 0., 1.]),
array([-0.40911067, -0.13171307, 0.14568452, 0.42308211, 0.7004797 ,
0.97787729, 1.25527488, 1.53267247, 1.81007006, 2.08746765,
2.36486525]),
)
numpy.random.randint(low, high=None, size=None, dtype=’l’)
# 返回[0,1)之间的整数,所以只有0
np.random.randint(10,size=5)
array([9, 2, 9, 0, 0])
np.random.randint(2,10,size=5)
array([9, 7, 2, 5, 4])
np.random.randint(2,10,size=(2,5))
array([[9, 7, 9, 2, 9],
[3, 3, 7, 2, 9]])
# 返回1个[1,5)时间的随机整数
np.random.randint(1,5)
4
# 返回 -5到5之间不包含5的 2行2列数据
np.random.randint(-5,5,size=(2,2))
array([[ 2, 3],
[-3, 1]])
numpy.random.sample(size=None)
返回半开区间内的随机浮点数[0.0,1.0)。
np.random.sample(size=(2,3))
np.random.sample(size=(2,2,3))
array([[[0.68697443, 0.81013166, 0.22536897],
[0.98997646, 0.55061188, 0.26891658]],
[[0.14787701, 0.16123889, 0.60404242],
[0.00403928, 0.06413641, 0.71548372]]])
使用相同的seed()值,则每次生成的随机数都相同,使得随机数可以预测
但是,只在调用的时候seed()一下并不能使生成的随机数相同,需要每次调用都seed()一下,表示种子相同,从而生成的随机数相同。
np.random.seed(2)
L1 = np.random.randn(3, 3)
L2 = np.random.randn(3, 3)
print(L1)
print("-"*10)
print(L2)
[[-0.41675785 -0.05626683 -2.1361961 ]
[ 1.64027081 -1.79343559 -0.84174737]
[ 0.50288142 -1.24528809 -1.05795222]]
----------
[[-0.90900761 0.55145404 2.29220801]
[ 0.04153939 -1.11792545 0.53905832]
[-0.5961597 -0.0191305 1.17500122]]
np.random.seed(1)
L1 = np.random.randn(3, 3)
np.random.seed(1)
L2 = np.random.randn(3, 3)
print(L1)
print("-"*10)
print(L2)
[[ 1.62434536 -0.61175641 -0.52817175]
[-1.07296862 0.86540763 -2.3015387 ]
[ 1.74481176 -0.7612069 0.3190391 ]]
----------
[[ 1.62434536 -0.61175641 -0.52817175]
[-1.07296862 0.86540763 -2.3015387 ]
[ 1.74481176 -0.7612069 0.3190391 ]]
numpy.random.normal(loc=0.0, scale=1.0, size=None)
作用:返回一个由size指定形状的数组,数组中的值服从 μ=loc,σ=scale 的正态分布。
参数:
# 标准正态分布,3行2列
a = np.random.normal(0, 1, (3, 2))
print(a)
print('-'*20)
# 均值为1,标准差为3
b = np.random.normal(1, 3, (3, 2))
print(b)
[[-0.24937038 1.46210794]
[-2.06014071 -0.3224172 ]
[-0.38405435 1.13376944]]
--------------------
[[-2.2996738 0.48271538]
[-1.63357525 1.12664124]
[ 2.74844564 -2.30185753]]
函数名称 | 描述说明 |
---|---|
resize | 返回指定形状的新数组。 |
append | 将元素值添加到数组的末尾。 |
insert | 沿规定的轴将元素值插入到指定的元素前。 |
delete | 删掉某个轴上的子数组,并返回删除后的新数组。 |
argwhere | 返回数组内符合条件的元素的索引值。 |
unique | 用于删除数组中重复的元素,并按元素值由大到小返回一个新数组。 |
sort() | 对输入数组执行排序,并返回一个数组副本 |
argsort | 沿着指定的轴,对输入数组的元素值进行排序,并返回排序后的元素索引数组 |
numpy.resize(arr, shape)
numpy.resize() 返回指定形状的新数组。
numpy.resize(arr,shape) 和ndarray.resize(shape, refcheck=False)区别:
a = np.array([[1,2,3],[4,5,6]])
print('a数组:',a)
#a数组的形状
print('a数组形状:',a.shape)
a数组: [[1 2 3]
[4 5 6]]
a数组形状: (2, 3)
b = np.resize(a,(3,3))
b
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3]])
a
array([[1, 2, 3],
[4, 5, 6]])
a.resize((3,3),refcheck=False)
a
array([[1, 2, 3],
[4, 5, 6],
[0, 0, 0]])
在数组的末尾添加值,默认返回一个一维数组。
numpy.append(arr, values, axis=None)
参数说明:
a = np.array([[1,2,3],[4,5,6]])
#向数组a添加元素
print (np.append(a, [7,8,9]))
[1 2 3 4 5 6 7 8 9]
print(a)
#沿轴 0 添加元素
print (np.append(a, [[7,8,9]],axis = 0))
[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]
[7 8 9]]
#沿轴 1 添加元素
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
[[1 2 3 5 5 5]
[4 5 6 7 8 9]]
表示沿指定的轴,在给定索引值的前一个位置插入相应的值,如果没有提供轴,则输入数组被展开为一维数组。
numpy.insert(arr, obj, values, axis)
参数说明:
a = np.array([[1,2],[3,4],[5,6]])
#不提供axis的情况,会将数组展开
print (np.insert(a,3,[11,12]))
[ 1 2 3 11 12 4 5 6]
#沿轴 0 垂直方向
print (np.insert(a,1,[11],axis = 0))
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
#沿轴 1 水平方向
print (np.insert(a,1,11,axis = 1))
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
该方法表示从输入数组中删除指定的子数组,并返回一个新数组。它与 insert() 函数相似,若不提供 axis 参数,则输入数组被展开为一维数组。
numpy.delete(arr, obj, axis)
参数说明:
a = np.arange(12).reshape(3,4)
print(a)
print(np.delete(a,5))
print(np.delete(a,6))
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[ 0 1 2 3 4 6 7 8 9 10 11]
[ 0 1 2 3 4 5 7 8 9 10 11]
#删除第二列
print(np.delete(a,1,axis = 1))
print(a)
#a = np.array([1,2,3,4,5,6,7,8,9,10])
#删除多行
print(np.delete(a,[1,2],axis = 0))
# 注意不能使用切片的形式
# print(np.delete(a,[1:4]))
[[ 0 2 3]
[ 4 6 7]
[ 8 10 11]]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[0 1 2 3]]
该函数返回数组中非 0 元素的索引,若是多维数组则返回行、列索引组成的索引坐标。
x = np.arange(6).reshape(2,3)
x
array([[0, 1, 2],
[3, 4, 5]])
x[x>2]
array([3, 4, 5])
print(x)
#返回所有大于1的元素索引
y=np.argwhere(x>1)
print("-"*10)
print(y,y.shape)
[[0 1 2]
[3 4 5]]
----------
[[0 2]
[1 0]
[1 1]
[1 2]] (4, 2)
用于删除数组中重复的元素,其语法格式如下:
numpy.unique(arr, return_index, return_inverse, return_counts)
参数说明:
a = np.array([5,2,6,2,7,5,6,8,2,9])
print (a)
# 对a数组的去重
uq = np.unique(a)
print(uq)
[5 2 6 2 7 5 6 8 2 9]
[2 5 6 7 8 9]
print("a:",a)
arr, old_indexes = np.unique(a, return_index=True)
print(arr)
print('-'*20)
print('old_indexes:', old_indexes)
arr, new_indexes = np.unique(a, return_inverse=True)
print(arr)
print('-'*20)
print('new_indexes:', new_indexes)
a: [5 2 6 2 7 5 6 8 2 9]
[2 5 6 7 8 9]
--------------------
old_indexes: [1 0 2 4 7 9]
[2 5 6 7 8 9]
--------------------
new_indexes: [1 0 2 0 3 1 2 4 0 5]
print("a:",a)
# 返回去重元素的重复数量
arr,index_counts = np.unique(a,return_counts = True)
print (arr)
# 元素出现次数:
print (index_counts)
a: [5 2 6 2 7 5 6 8 2 9]
[2 5 6 7 8 9]
[3 2 2 1 1 1]
对输入数组执行排序,并返回一个数组副本。
numpy.sort(a, axis, kind, order)
参数说明:
a = np.array([[3,7,5],[6,1,4]])
print('a数组是:', a)
#调用sort()函数
print('排序后的内容:',np.sort(a))
a
a数组是: [[3 7 5]
[6 1 4]]
排序后的内容: [[3 5 7]
[1 4 6]]
array([[3, 7, 5],
[6, 1, 4]])
#以行为参照,列上面的数据排序:
print(np.sort(a, axis = 0))
[[3 1 4]
[6 7 5]]
#以列为参照,行上面的数据排序:
print(np.sort(a, axis = 1))
[[3 5 7]
[1 4 6]]
dt = np.dtype([('name','S10'),('age', int)])
arr = np.array([('blossom',20),('insomnia',20)],dtype=dt)
print(arr)
print('--'*20)
print(np.sort(arr,order='name'))
[(b'blossom', 20) (b'insomnia', 20)]
----------------------------------------
[(b'blossom', 20) (b'insomnia', 20)]
argsort() 沿着指定的轴,对输入数组的元素值进行排序,并返回排序后的元素索引数组。示例如下:
a = np.array([90,29,89,12])
print(a)
sort_ind = np.argsort(a)
print('sort_ind:',sort_ind)
sort_a = a[sort_ind]
print('sort_a:', sort_a)
[90 29 89 12]
sort_ind: [3 1 2 0]
sort_a: [12 29 89 90]