Python数据分析之Numpy操作大全
从头到尾都是手码的,文中的所有示例也都是在Pycharm中运行过的,自己整理笔记的最大好处在于可以按照自己的思路来构建框架,等到将来在需要的时候能够以最快的速度看懂并应用=_=
注:为方便表述,本章设arr为numpy.ndarray的一个实例化对象
1. NumPy简介
NumPy是python运用于数据分析、科学计算最重要的库之一
由于numpy底层是用C/C++写的,在性能和速度上都有较大的提升,能用NumPy的地方就多用NumPy
官网:www.numpy.org
约定俗成的NumPy模块载入方法:
import numpy as np
2. ndarray简介
numpy.ndarray(n-dimensional array, n维数组)是NumPy中的一个类,它类似于list,是一种数据容器,但是比list功能更强大
ndarray要求它里面的所有元素都是相同的数据类型,以便于向量化(vectorization)
ndarray在print时,元素与元素之间无逗号,如[1 2 3]
ndarray也支持拆包,如a,b = np.array([1,2])
3. ndarray对象的属性
(1)arr.ndim
ndarray的维度
抽象地说是ndarray有几个坐标轴方向
形象地说是np.array()在定义时,里面的[]加()一共有几层嵌套,维度就是几
(2)arr.shape
ndarray的形状,是衡量各个维度大小的元组,元组中有几项就是几维
一维时等于(元素个数,)
,二维时等于(行数,列数)
,三维时等于(x轴的长度,y轴的长度,z轴的长度)
记住一维和二维代表的具体意义即可
(3)arr.size
ndarray的长度,等于.shape元组中各项的乘积
(4)arr.dtype
dtype是data type的简写,返回ndarray里面的元素的数据类型:整数为int32
、浮点数为float64
、字符串为<U6
(5)arr.itemsize
每个元素的字节长度
(6)arr.nbytes
整个数组的字节长度,等于 arr.itemsize * arr.size
# 一维ndarray
import numpy as np
close_list = [10, 10.5, 11.0, 11.5, 12.0]
close = np.array(close_list)
print(close)
print('ndim: ', close.ndim)
print('shape: ', close.shape)
print('size: ', close.size)
print('dtype: ', close.dtype)
执行结果:
[10. 10.5 11. 11.5 12. ]
ndim: 1
shape: (5,)
size: 5
dtype: float64
# 二维ndarray
import numpy as np
open_list = [10, 11, 12, 13, 14]
close_list = [12, 11, 10, 14, 16]
stock_info = np.array([open_list, close_list])
print(stock_info)
print('ndim: ', stock_info.ndim)
print('shape: ', stock_info.shape)
print('size: ', stock_info.size)
print('dtype: ', stock_info.dtype)
执行结果:
[[10 11 12 13 14]
[12 11 10 14 16]]
ndim: 2
shape: (2, 5)
size: 10
dtype: int32
# 三维ndarray
import numpy as np
arr = np.array([
[[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]],
])
print(arr)
print('ndim: ', arr.ndim)
print('shape: ', arr.shape)
print('size: ', arr.size)
print('dtype: ', arr.dtype)
执行结果:
[[[ 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]]]
ndim: 3
shape: (2, 4, 4)
size: 32
dtype: int32
4. ndarray的创建
(1)使用np.array()或np.asarray()创建
① np.array(list)
最常用的创建方式之一,特别地,一维ndarray本身不区分行和列,二位ndarray用内层[]表示一行的结束,因此np.array([[1],[2],[3]])
是3行1列的列向量,np.array([[1,2,3]])
是1行3列的行向量。绝大部分情况下都使用的是列向量,因为ndarray中的所有元素数据类型相同,对应的是数据库中的一列(一个字段)。
若在创建ndarray时里面的元素既有int也有float,则会将所有int转化为float(对其他方式创建也适用)
import numpy as np
a=np.array([1,2.99,3])
print(a,type(a))
执行结果:
[1. 2.99 3. ] <class 'numpy.ndarray'>
若在创建ndarray时里面的元素既有数字又有字符串,则会将所有数字转化为字符串(对其他方式创建也适用)
import numpy as np
a=np.array([1,2.99,'3'])
print(a,type(a))
执行结果:
['1' '2.99' '3'] <class 'numpy.ndarray'>
② np.array(tuple)
import numpy as np
stock_info_tuple = ('000001', '平安银行', '银行', 10.20)
stock_info_array = np.array(stock_info_tuple)
print(stock_info_array)
执行结果:
['000001' '平安银行' '银行' '10.2']
③ np.array(range())
不推荐将range()通过这种方法生成ndarray,繁琐,应使用更为简便的np.arange(n)
import numpy as np
arr = np.array(range(5))
print(arr)
执行结果:[0 1 2 3 4]
④ np.array(pandas.Series)和np.array(pandas.DataFrame)
可以将pandas.Series和pandas.DataFrame转化为ndarray
应用场景:进行技术分析的talib模块只支持ndarray,不支持pandas.Series和pandas.DataFrame数据类型
import pandas as pd
import numpy as np
s = pd.Series([1,2,3],index=['t1','t2','t3'])
df = pd.DataFrame([[44, 55, 66],[77, 88, 99]],columns=['c1','c2','c3'],index=['t1','t2'])
arr1 = np.asarray(s)
arr2 = np.asarray(df)
print(arr1)
print(type(arr1))
print(arr2)
print(type(arr2))
执行结果:
[1 2 3]
<class 'numpy.ndarray'>
[[44 55 66]
[77 88 99]]
<class 'numpy.ndarray'>
⑤ np.asarray()
np.asarray()和np.array用法基本相同,前文所述各种数据类型也都可以使用np.asarray()转换为ndarray
(2)使用np.arange()创建
语法:np.arange(起始值,结束值,步长)
与range()相同,起始值默认为0,步长默认为1,即可以简写成np.arange(结束值)
和range()相比,都是顾头不顾尾原则,但是支持步长非整数的情况,同时写起来也比np.array(range(n))更简便
import numpy as np
arr = np.arange(5)
print(arr)
执行结果:[0 1 2 3 4]
import numpy as np
arr = np.arange(0,1,0.1)
print(arr)
执行结果:[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
(3)使用np.zeros()、np.ones()、np.empty()创建
① np.zeros()
语法:np.zeros(shape,dtype=float)
生成一个由0组成的ndarray
第一个参数shape:一个整数(对应1维)或一个元组(元组中有几个元素就是几维)
第二个参数dtype:默认值是'f'或float
(浮点数),可以改为'i'或int
(整数)、complex
(复数)
import numpy as np
zeros_1d_array = np.zeros(5) # 一维,长度为5
# zeros_1d_array = np.zeros((5,)) # 一维,长度为5,使用元组的表示方法
zeros_2d_array = np.zeros((3,4),int) # 二维,3行4列
zeros_3d_array = np.zeros((2,2,2),dtype='i') # 三维
print(zeros_1d_array); print('==================')
print(zeros_2d_array); print('==================')
print(zeros_3d_array)
执行结果:
[0. 0. 0. 0. 0.]
==================
[[0 0 0 0]
[0 0 0 0]
[0 0 0 0]]
==================
[[[0 0]
[0 0]]
[[0 0]
[0 0]]]
② np.ones()
np.ones()和np.zeros()完全类似,就是把0换成了1,不再赘述
③ np.empty()
与np.zeros()和np.ones()类似,只不过填充的是一些非常小的、接近0的数字
import numpy as np
zeros_1d_array = np.empty(5) # 一维,长度为5
# zeros_1d_array = np.empty((5,)) # 一维,长度为5,使用元组的表示方法
zeros_2d_array = np.empty((3,4)) # 二维,3行4列
zeros_3d_array = np.empty((2,2,2)) # 三维
print(zeros_1d_array); print('==================')
print(zeros_2d_array); print('==================')
print(zeros_3d_array)
执行结果:
[4.58792637e-278 6.47377963e-273 4.24265622e-268 2.78046718e-263
1.74758669e-104]
==================
[[7.e-322 0.e+000 0.e+000 0.e+000]
[0.e+000 0.e+000 0.e+000 0.e+000]
[0.e+000 0.e+000 0.e+000 0.e+000]]
==================
[[[7.76e-322 0.00e+000]
[0.00e+000 0.00e+000]]
[[0.00e+000 9.88e-322]
[0.00e+000 0.00e+000]]]
④ 意义
在实际应用中,一般都是先通过np.zeros()或np.ones()获得一个确定了shape的模子,然后再对里面的具体数据进行修改
(4)使用np.zeros_like()、np.ones_like()、np.empty_like()创建
① np.zeros_like()
语法:np.zeros_like(ndarray)
输入的参数是一个ndarray,生成一个结构与之相同但全由0填充的ndarray
这里的结构相同是指:shape相同 + 数据类型相同
② np.ones_like()
语法:np.ones_like(ndarray)
输入的参数是一个ndarray,生成一个结构与之相同但全由1填充的ndarray
这里的结构相同是指:shape相同 + 数据类型相同
③ np.empty_like()
语法:np.empty_like(ndarray)
输入的参数是一个ndarray,生成一个结构与之相同但全由特别大或特别小的数填充的ndarray
这里的结构相同是指:shape相同 + 数据类型相同
(5)使用np.linspace()创建
linspace是线性等分向量(linear space)的缩写,注意方法名中间没有字母e
语法:np.linspace(起始值,结束值,切分份数=50)
注意:
- 起始值、结束值都是可以取到的(和“顾头不顾尾”原则不同)
- 切分份数指的就是返回的一维ndarray中有几个元素,其默认值为50
import numpy as np
arr = np.linspace(1,5,4) # 从1到5,等距离分成4份
print(arr)
执行结果:
[1. 2.33333333 3.66666667 5.]
(6)使用np.eye()、np.identity()创建
语法:np.eye(n)
、np.eye(a,b)
、np.identity(n)
np.eye()可以生成一个单位矩阵(二维ndarray),可以是n行n列正方形,也可以是a行b列长方形
np.identity()则只能生成正方形的单位矩阵
import numpy as np
arr1 = np.eye(2)
arr2 = np.eye(3,4)
arr3 = np.identity(2)
# arr4 = np.identity((3,4)) # 报错
print(arr1); print('===========')
print(arr2); print('===========')
print(arr3)
执行结果:
[[1. 0.]
[0. 1.]]
===========
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]]
===========
[[1. 0.]
[0. 1.]]
(7)使用np.diagflat()创建
语法:np.diagflat(v)
生成以指定列表或一维ndarray为对角线元素的方阵(二维ndarray)
参数v可以是list、ndarray等
import numpy as np
arr1 = np.array([1,2,3])
arr2 = np.diagflat(arr1) # 参数是ndarray
arr3 = np.diagflat([4,5,6]) # 参数是list
print(arr1); print('===========')
print(arr2); print('===========')
print(arr3)
执行结果:
[1 2 3]
===========
[[1 0 0]
[0 2 0]
[0 0 3]]
===========
[[4 0 0]
[0 5 0]
[0 0 6]]
(8)使用随机数方法创建
详见本章“一.9.NumPy随机数”
5. ndarray的索引和切片
(1)一维ndarray的索引和切片方法
与列表的方法大体相同,新增了花式索引(Fancy Indexing):
import numpy as np
a = np.arange(10,20)
print(a)
print(a[[8,2,5]])
执行结果:
[10 11 12 13 14 15 16 17 18 19]
[18 12 15]
注意:花式索引通过list实现,因此数字外面要套两层中括号[[]],如果只有一层将报错
(2)二维ndarray的索引和切片方法
import numpy as np
arr = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]])
print(arr,'\n')
# 选取某一行
print('选取第一行推荐方法\n', arr[0,:])
print('选取第一行这样也行\n',arr[0])
# 选取某一列
print('选取最后一列\n', arr[:,-1])
# 选取某一行某一列上的元素
print('选取倒数第二行第三列的元素\n', arr[-2,2])
# 选取某几行中的某几列(纯切片)
print('选取倒数第二行到最后一行,列索引号为奇数的元素\n', arr[-2:,1::2])
# 选取某几行中的某几列(切片+花式索引)
print('选取第一行到第三行,第一、五、四列的元素\n', arr[:3,[0,4,3]])
执行结果:
[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]
[16 17 18 19 20]]
选取第一行推荐方法
[1 2 3 4 5]
选取第一行这样也行
[1 2 3 4 5]
选取最后一列
[ 5 10 15 20]
选取倒数第二行第三列的元素
13
选取倒数第二行到最后一行,列索引号为奇数的元素
[[12 14]
[17 19]]
选取第一行到第三行,第一、五、四列的元素
[[ 1 5 4]
[ 6 10 9]
[11 15 14]]
(3)布尔值索引
对二维ndarray的某行或某几行按照一定的条件进行筛选,返回该ndarray某一行的对应项组成的新的ndarray
多条件筛选时,&代表“且”,|代表“或”(不能写成and、or),并且要注意每个条件外面需要加小括号()
示例代码见“第五章 Python编程进阶 - 一、NumPy模块 - 8. ndarray对象的方法和NumPy模块的方法 - (2)二元通用函数 - ③ 基本逻辑运算
”
(4)查找非0元素的索引
语法:np.nonzero(arr)
以元组的形式返回一个ndarray中的非0元素索引号,ndarray可以是一维也可以是多维,每个维度分别对应结果元组中的一项
import numpy as np
a = np.array([8,8,0,8]) # 一维ndarray
b = np.array([[3, 0, 0],
[0, 4, 0], # 二维ndarray
[5, 6, 0]])
result_a = np.nonzero(a)
result_b = np.nonzero(b)
print(result_a)
print(result_b)
print(type(result_a))
print(type(result_b))
执行结果:
(array([0, 1, 3], dtype=int64),)
(array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64))
<class 'tuple'>
<class 'tuple'>
解释:
一维的结果说明非0元素的索引号为:0,1,3
二维的结果说明非0元素的索引号为:(0,0),(1,1),(2,0),(2,1)
6. ndarray的向量化和广播
(1)向量化(vectorization)
ndarray很重要正是因为它提供了可以批处理数据而不需要写任何for循环的向量化运算。
在向量化运算中,参与运算的都是两个shape相同的ndarray,进行元素级操作,相同位置的元素按照某种运算规则进行运算。
向量化的运算速度比Python的for循环要快上两个数量级,可以有效提升代码性能。
import numpy as np
return_array = np.array([0.1, 0.12, 0.3, 0.06, -0.05])
delta_return_array = np.array([0.05, 0.02, 0.1, 0.02, 0.01])
leverage_array = np.array([2, 1.5, 2, 3, 1])
print(return_array + delta_return_array) # 向量化加法
print(return_array - delta_return_array) # 向量化减法
print(return_array * leverage_array) # 向量化乘法
print(return_array / leverage_array) # 向量化除法
print(return_array ** leverage_array) # 向量化乘方
执行结果:
[ 0.15 0.14 0.4 0.08 -0.04]
[ 0.05 0.1 0.2 0.04 -0.06]
[ 0.2 0.18 0.6 0.18 -0.05]
[ 0.05 0.08 0.15 0.02 -0.05]
[ 0.01 0.04156922 0.09 0.000216 -0.05]
(2)广播(Broadcasting)
① ndarray与数字进行计算
对于ndarray与数字进行的+、-、*、/、**、//、%、>、<、>=、<=、==、!=等运算,会将这个ndarray中的每一个元素均与这个数字进行计算,并用这些结果组成一个与原ndarray结构相同的ndarray
import numpy as np
arr=np.array([1,2,3])
print(arr+2)
print(arr>2)
执行结果:
[3 4 5]
[False False True]
② 二维ndarray与一维对象进行计算
这个计算有个前提,即二维ndarray的列数等于一维对象的长度,在满足这个前提的情况下(不满足则报错),会将二维ndarray的每一行均与一维对象进行计算,并用这些结果组成一个与二维ndarray结构相同的ndarray
import numpy as np
arr = np.array([
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]
])
delta = [3,3,2,2,2]
print(arr); print('=====================')
print(arr+delta); print('=====================')
print(arr-delta); print('=====================')
print(arr*delta); print('=====================')
print(arr/delta); print('=====================')
print(arr**delta)
执行结果:
[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]]
=====================
[[ 4 5 5 6 7]
[ 9 10 10 11 12]
[14 15 15 16 17]]
=====================
[[-2 -1 1 2 3]
[ 3 4 6 7 8]
[ 8 9 11 12 13]]
=====================
[[ 3 6 6 8 10]
[18 21 16 18 20]
[33 36 26 28 30]]
=====================
[[0.33333333 0.66666667 1.5 2. 2.5 ]
[2. 2.33333333 4. 4.5 5. ]
[3.66666667 4. 6.5 7. 7.5 ]]
=====================
[[ 1 8 9 16 25]
[ 216 343 64 81 100]
[1331 1728 169 196 225]]
#练习
import numpy as np
a = np.zeros((5,5))
a += np.arange(5) # 写成Z = Z + np.array([0,1,2,3,4])更便于理解
print(a)
执行结果:
[[0. 1. 2. 3. 4.]
[0. 1. 2. 3. 4.]
[0. 1. 2. 3. 4.]
[0. 1. 2. 3. 4.]
[0. 1. 2. 3. 4.]]
关于两个ndarray之间的乘法
两个ndarray之间的*
并不是矩阵乘法,对ndarray计算矩阵乘法应使用np.dot(arr1,arr2)
或arr1.dot(arr2)
(dot是点乘的意思),不过这样并不严谨,因为一维ndarray本身不区分行和列,分不清到底乘的是行向量还是列向量。
因此矩阵乘法建议使用matrix数据类型进行*
的计算,详见本章“四.10NumPy线性代数”。
import numpy as np
a = np.array([[3, 1], [1, 2]])
b = np.array([2, 3])
print(a*b) # 基于向量化、广播计算的乘法
print('=========')
print(np.dot(a,b)) # 矩阵乘法(不严谨:这里的b应该是列向量,但是一维ndarray本身不区分行、列)
print('=========')
print(a.dot(b)) # 矩阵乘法
执行结果:
[[6 3]
[2 6]]
=========
[9 8] # 不严谨:这里得到的应该是列向量,但是一维ndarray本身不区分行、列
=========
[9 8] # 不严谨
7. ndarray的修改、变形、转换
(1)修改shape
① 基于arr.reshape()
语法:arr.reshape(new_shape)
将一个ndarray的shape进行调整
参数new_shape:一个整数(对应1维)或一个元组(元组中有几个元素就是几维)
注意:
- 新的ndarray的size必须等于原ndarray的size(否则报错)
- 当new_shape是二维时,其中一个参数可以是-1,代表此维度由size/另一维度自动计算得出。此时另一个维度必须是能size整除的整数(否则报错)。此外,两个维度不能同为-1(否则报错)。
- 原ndarray并未发生改变,因此需要定义一个新的变量来接收这个新的ndarray
import numpy as np
a = np.arange(1,25)
b = a.reshape((4,6))
c = b.reshape((3,-1))
d = b.reshape((-1,12))
e = b.reshape(24)
# e = b.reshape((24,)) # 这样写e也可以
# f = b.reshape(7,-1) # 报错,7不能被24整除
# g = b.reshape(-1,-1) # 报错,两个维度不能同为-1
print(a); print('===============')
print(b); print('===============')
print(c); print('===============')
print(d); print('===============')
print(e)
执行结果:
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
===============
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]
[13 14 15 16 17 18]
[19 20 21 22 23 24]]
===============
[[ 1 2 3 4 5 6 7 8]
[ 9 10 11 12 13 14 15 16]
[17 18 19 20 21 22 23 24]]
===============
[[ 1 2 3 4 5 6 7 8 9 10 11 12]
[13 14 15 16 17 18 19 20 21 22 23 24]]
===============
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
② 基于np.reshape()
语法:np.reshape(arr,new_shape)
将一个ndarray的shape进行调整
两个参数:
- arr:numpy.ndarray的一个实例化对象
- new_shape:一个整数(对应1维)或一个元组(元组中有几个元素就是几维)
和arr.reshape()完全相同,不再赘述
import numpy as np
a = np.arange(1,25)
b = np.reshape(a,(4,6))
c = np.reshape(b,(3,-1))
d = np.reshape(b,(-1,12))
e = np.reshape(b,24)
# e = np.reshape(b,(24,)) # 这样写e也可以
# f = np.reshape(b,(7,-1)) # 报错,7不能被24整除
# g = np.reshape(b,(-1,-1)) # 报错,两个维度不能同为-1
print(a); print('===============')
print(b); print('===============')
print(c); print('===============')
print(d); print('===============')
print(e)
执行结果:
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
===============
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]
[13 14 15 16 17 18]
[19 20 21 22 23 24]]
===============
[[ 1 2 3 4 5 6 7 8]
[ 9 10 11 12 13 14 15 16]
[17 18 19 20 21 22 23 24]]
===============
[[ 1 2 3 4 5 6 7 8 9 10 11 12]
[13 14 15 16 17 18 19 20 21 22 23 24]]
===============
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
(2)修改size
① 基于arr.resize()
语法:arr.resize(new_shape, refcheck=True)
将一个ndarray的size进行调整
参数:
- new_shape:一个整数(对应1维)或一个元组(元组中有几个元素就是几维)
- refcheck:布尔值,是否执行一个检验,一般不用加这个参数,如果未加此参数时报错,可以尝试加上refcheck=False关掉检验
注意:
- 直接在原ndarray上进行原地修改,resize()操作无返回值(如果定义新变量来接收,则其为None)
- 新的ndarray的size可以小于、等于、大于原ndarray的size。若大于,则用0来填补后面的空项
import numpy as np
a = np.arange(1,25)
print(a); print('===============')
a.resize((2,12))
print(a); print('===============')
a.resize((3,3))
print(a); print('===============')
a.resize(12)
# a.resize((12,))
print(a)
执行结果:
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
===============
[[ 1 2 3 4 5 6 7 8 9 10 11 12]
[13 14 15 16 17 18 19 20 21 22 23 24]]
===============
[[1 2 3]
[4 5 6]
[7 8 9]]
===============
[1 2 3 4 5 6 7 8 9 0 0 0]
② 基于np.resize()
语法:np.size(arr,new_shape)
将一个ndarray的size进行调整
两个参数:
arr:numpy.ndarray的一个实例化对象
new_shape:一个整数(对应1维)或一个元组(元组中有几个元素就是几维)
注意:
- 非原地修改,需要定义一个新的变量来接收np.resize()的返回值
- 新的ndarray的size可以小于、等于、大于原ndarray的size。若大于,则会回到起始位置来填补后面的空项
import numpy as np
a = np.arange(1, 25)
b = np.resize(a, (2, 12))
c = np.resize(b, (3, 3))
d = np.resize(c, 12)
# d = np.resize(c, (12,))
print(a); print('===============')
print(b); print('===============')
print(c); print('===============')
print(d)
执行结果:
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
===============
[[ 1 2 3 4 5 6 7 8 9 10 11 12]
[13 14 15 16 17 18 19 20 21 22 23 24]]
===============
[[1 2 3]
[4 5 6]
[7 8 9]]
===============
[1 2 3 4 5 6 7 8 9 1 2 3]
(3)转置
语法:arr.T
或arr.transpose()
,两种方式等效
将ndarray转置:
- 一维ndarray不分行或列,转置完了还是自己
- 二维ndarray的shape由转置前的(m,n)变为(n,m)
- 多维ndarray的shape由转置前的(k1,k2,...,kn)变为(kn,...,k2,k1)
# 一维ndarray的转置
import numpy as np
a = np.arange(1,7)
print(a,a.shape)
b = a.T
print(a,a.shape); print(b,b.shape)
c = a.transpose()
print(a,a.shape); print(c,c.shape)
执行结果:
[1 2 3 4 5 6] (6,)
[1 2 3 4 5 6] (6,)
[1 2 3 4 5 6] (6,)
[1 2 3 4 5 6] (6,)
[1 2 3 4 5 6] (6,)
# 二维ndarray的转置
import numpy as np
a = np.arange(1,7)
a.resize((2,3))
b = a.T
c = b.transpose()
print(a); print('===============')
print(b); print('===============')
print(c)
执行结果:
[[1 2 3]
[4 5 6]]
===============
[[1 4]
[2 5]
[3 6]]
===============
[[1 2 3]
[4 5 6]]
(4)将多维ndarray变为一维
flatten: v.压平
语法:arr.flatten(order='C')
参数order:可选参数,为取值顺序,默认为'C'
,即按行取;也可以是'F'
,即按列取
import numpy as np
a = np.arange(1,10).reshape(3,3)
print(a); print('===============')
b = a.flatten()
print(a); print('===============')
print(b); print('===============')
c = a.flatten(order='F')
print(c)
执行结果:
[[1 2 3]
[4 5 6]
[7 8 9]]
===============
[[1 2 3]
[4 5 6]
[7 8 9]]
===============
[1 2 3 4 5 6 7 8 9]
===============
[1 4 7 2 5 8 3 6 9]
(5)修改ndarray中指定元素的值
语法:arr[索引]=值
原则上只能修改成相同数据类型的值。若改变了数据类型,则有以下规则:
- 将已有的int组成的ndarray中的某项元素修改为float时,只会将该float截取整数部分后进行保存
import numpy as np
b=np.array([1,2,3])
print(b,type(b))
b[1]=45.67
print(b,type(b))
执行结果:
[1 2 3] <class 'numpy.ndarray'>
[1 45 3] <class 'numpy.ndarray'>
- 将已有的字符串组成的ndarray中的某项元素修改为数字时,先将数字统一转为字符串,再按照原ndarray最长的元素的长度对替换后的字符串进行截取
import numpy as np
b=np.array(['a','bc','def'])
print(b,type(b))
b[0]=12.34
b[1]=56789
print(b,type(b))
执行结果:
['a' 'bc' 'def'] <class 'numpy.ndarray'>
['12.' '567' 'def'] <class 'numpy.ndarray'>
- 将已有的int组成的ndarray中的某项元素修改为字符串时,会将对应的数字修改为
int(给定的字符串)
,当给定的字符串里含有除负号“-
”以外的字母或特殊字符时,会报错 - 将已有的float组成的ndarray中的某项元素修改为字符串时,会将对应的数字修改为
float(给定的字符串)
,当给定的字符串里含有float()不支持的字母或特殊字符时,会报错
(6)对ndarray中的元素进行排序
语法:arr.sort()或np.sort(arr)
arr.sort()无返回值,直接在原ndarray上执行升序排列;np.sort(arr)不会更改原ndarray,而是产生一个升序排列后的新的ndarray
两种方法都仅支持升序排列,不支持降序排列
import numpy as np
a1 = np.array([3,1,4,2])
a2 = np.array([3,1,4,2])
b1 = a1.sort()
b2 = np.sort(a2)
print(a1)
print(a2)
print(b1)
print(b2)
执行结果:
[1 2 3 4]
[3 1 4 2]
None
[1 2 3 4]
(7)对两个ndarray进行拼接
横向拼接:np.hstack([arr1,arr2])
或np.append(arr1,arr2)
纵向拼接:np.vstack([arr1,arr2])
注意:np.append()更像是list的extend方法(迭代追加,将arr2中的每个元素追加到arr1中),而不像list的append方法(把整个arr2作为一个元素追加到arr1中)
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.append(a,b)
d = np.hstack([a,b])
e = np.vstack([a,b])
print(c); print('========')
print(d); print('========')
print(e)
执行结果:
[1 2 3 4 5 6]
========
[1 2 3 4 5 6]
========
[[1 2 3]
[4 5 6]]
(8)对ndarray进行去重
语法:np.unique(arr)
将ndarray中的所有元素去重,然后按由小到大顺序排列,无论输入的arr是几维的,都返回一个一维ndarray
import numpy as np
arr1 = np.unique(np.array([6,2,3,1,4,1,2,5]))
arr2 = np.unique(np.array([[6,2,3],[1,4,1],[2,5,3]]))
print(arr1)
print(arr2)
执行结果:
[1 2 3 4 5 6]
[1 2 3 4 5 6]
(9)将ndarray转换为其他数据格式
① 将ndarray转换为list
语法:arr.tolist()
此方法不会对arr本身进行修改,因此需要定义一个新的变量来接收产生的list
② 将ndarray转换为矩阵
语法:np.asmatrix(arr)
特别地,若arr是一个一维ndarray,则得到的将是一个行向量(即1行n列的矩阵)
import numpy as np
a = np.array([1,2,3])
b = a.tolist()
c = np.asmatrix(a)
print(a,type(a))
print(b,type(b))
print(c,type(c))
执行结果:
[1 2 3] <class 'numpy.ndarray'>
[1, 2, 3] <class 'list'>
[[1 2 3]] <class 'numpy.matrix'>
8. ndarray对象的方法和NumPy模块的方法
(1)一元通用函数
通用函数(universal function)是指NumPy中对ndarray执行元素级运算的函数
分别对ndarray中的每项进行计算,并将结果组成一个新的ndarray
求绝对值:np.abs(arr)
求平方:np.square(arr)
求平方根:np.sqrt(arr)
指数运算:np.exp(arr)
对数运算:np.log(arr)
数据近似计算:
向下取整:np.floor(arr)
向上取整:np.ceil(arr)
四舍五入:arr.round(n)、np.round(arr,n)
符号判断:np.sign(arr),正数项返回1,负数项返回-1,0返回0。此外,也可以使用np.where()来实现更为复杂的根据判断结果返回指定值的功能。
(2)二元通用函数
分别对两个(shape相同的)ndarray中的对应项进行计算,并将结果组成一个新的ndarray
① 基本数学运算
- 加:arr1 + arr2
- 减:arr1 - arr2
- 乘:arr1 * arr2
- 除:arr1 / arr2
- 取余:arr1 % arr2
② 基本比较运算
大于:arr1 > arr2
大于等于:arr1 >= arr2
小于:arr1 < arr2
小于等于:arr1 <= arr2
等于:arr1 == arr2
不等于:arr1 != arr2
import numpy as np
arr1=np.array([1,2,3])
arr2=np.array([0,2,4])
print(arr1>arr2)
print(arr1==arr2)
print(arr1!=arr2) 执行结果:
[ True False False]
[False True False]
[ True False True]
③ 基本逻辑运算
用来对两个ndarray组成的条件(或两个布尔值类型的ndarray)执行逻辑运算,注意不要用Python原生的or、and、not进行运算否则报错,具体的运算符包括:
- 或:
(条件1) | (条件2)
、np.logical_or(条件1,条件2)
- 且:
(条件1) & (条件2)
、np.logical_and(条件1,条件2)
- 非:
~(条件1)
、np.logical_not(条件)
import numpy as np
code_array = np.array(['000001', '000002', '000003', '000004'])
pe_array = np.array([20, 10, 5, 30])
roe_array = np.array([0.05, -0.10, 0.12, 0.15])
# 单条件筛选
print(code_array[pe_array<=10]); print('===========')
# 单条件筛选(非)
print(code_array[~(pe_array<=10)])
print(code_array[np.logical_not(pe_array<=10)]); print('===========')
# 多条件筛选(且)
print(code_array[(pe_array<=10) & (roe_array>=0)])
print(code_array[np.logical_and(pe_array<=10,roe_array>=0)]); print('===========')
# 多条件筛选(或)
print(code_array[(pe_array<=10) | (roe_array>=0)])
print(code_array[np.logical_or(pe_array<=10,roe_array>=0)])
执行结果:
['000002' '000003']
===========
['000001' '000004']
['000001' '000004']
===========
['000003']
['000003']
===========
['000001' '000002' '000003' '000004']
['000001' '000002' '000003' '000004']
(3)统计相关方法
求和:arr.sum()、np.sum(arr)
import numpy as np
arr = np.array([[1,2,-3],[4,5,-6],[7,8,-9]])
print(arr.sum())
执行结果:9
# 将广播与sum()结合实现真值计数
import numpy as np
arr = np.array([[1,2,-3],[4,5,-6],[7,8,-9]])
print(arr); print('===========')
print(arr>0); print('===========')
print((arr>0).sum())
执行结果:
[[ 1 2 -3]
[ 4 5 -6]
[ 7 8 -9]]
===========
[[ True True False]
[ True True False]
[ True True False]]
===========
6
求平均值:简单平均arr.mean()、简单平均np.mean(arr)、加权平均np.average(arr)
求标准差:arr.std()、np.std(arr)
求Pearson相关系数矩阵:np.corrcoef(arr1,arr2),返回一个n行n列的ndarray
求最值及其索引:
求最大值:arr.max()、np.max(arr)
求最大值项的索引值:arr.argmax()、np.argmax(arr)
当有多项同为最大时,返回首个索引值
当arr为多维ndarray时,会将其转化为一维ndarray,并返回此一维ndarray的最大项索引值
import numpy as np
arr = np.array([[10,20,30],
[40,50,60],
[70,80,90]])
print(arr.argmax())
print(np.argmax(arr)) 执行结果:
8
8求最小值:arr.min()、np.min(arr)
求最小值项的索引值:arr.argmin()、np.argmin(arr)
当有多项同为最小时,返回首个索引值
当arr为多维ndarray时,会将其转化为一维ndarray,并返回此一维ndarray的最小项索引值
累积计算:
累积和(cumulative sum):arr.cumsum()、np.cumsum(arr)
累积积(cumulative product):arr.cumprod()、np.cumprod(arr)
注意:
- ndarray没有累积最大(cummax)、累积最小(cummin)这两种方法,但是pandas.DataFrame有
- 若计算的ndarray是多维的,会将其变为一维,然后再计算其累积和、累积积,返回的结果也是一维ndarray。这点和pandas.DataFrame不同,pandas.DataFrame直接用多维数据按列(或按行)计算累积值,不会将其变为一维再计算。
import numpy as np
arr = np.array([[2,2,2],[2,2,2],[2,2,2]])
print(arr.cumsum())
print(np.cumsum(arr))
print(arr.cumprod())
print(np.cumprod(arr)) 执行结果:
[ 2 4 6 8 10 12 14 16 18]
[ 2 4 6 8 10 12 14 16 18]
[ 2 4 8 16 32 64 128 256 512]
[ 2 4 8 16 32 64 128 256 512]
求近似分位数:np.percentile(arr,rate),其中rate代表百分之多少的分位数
注意:
- 这个函数计算的近似分位数是基于由小到大排列的分位数,因此如果想计算由大到小排列的分位数,rate应等于100减去目标百分数
- 之所以称为“近似”分位数,是因为Python对返回值进行了处理,得到的结果并不严格等于该位置上数据的值,见下例:
import numpy as np
arr = np.arange(100)
a = np.percentile(arr,10) # 最小的10%分位数
b = np.percentile(arr,20) # 最小的20%分位数
c = np.percentile(arr,80) # 最大的20%分位数
d = np.percentile(arr,90) # 最大的10%分位数
print(arr); print('===========')
print(a)
print(b)
print(c)
print(d); print('===========')
print(arr[arr<a]); print('-----------')
print(arr[arr<b]); print('-----------')
print(arr[arr>c]); print('-----------')
print(arr[arr>d])
执行结果:
[ 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]
===========
9.9
19.8
79.2
89.10000000000001
===========
[0 1 2 3 4 5 6 7 8 9]
-----------
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
-----------
[80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]
-----------
[90 91 92 93 94 95 96 97 98 99]
(4)其他重要方法
① np.where()
语法1:np.where(arr组成的判断条件, x, y)
当x和y都留空时,返回一个由索引号组成的ndarray组成的元组。此时,可以进一步通过arr[np.where(arr组成的判断条件)]
得到满足条件的项组成的新的arr(这里相当于应用了花式索引)
当x和y是一个具体的值时,返回一个与给定arr具有相同shape的新的arr,新的arr中每一项的值取决于给定arr中对应项的判断结果,为True时赋值x,为False时赋值y
当x和y是与arr具有相同shape的arr时,返回一个与给定arr具有相同shape的新的arr,新的arr中每一项的值取决于给定arr中对应项的判断结果,为True时从x的对应位置取值,为False时从y的对应位置取值
若第二个参数和第三个参数有一个留空、一个不留空,则报错
注意:
np.where()是一种重要的方法,它相当于向量化的if,使用它可以避免Python层面的循环嵌套if,应熟练掌握
np.where()只能满足状态有两种(True或False)的情况;
若状态有三种,则需要写两句np.where(),此时也可以考虑是否能用np.sign()完成需求;
若状态有N种,则需要写(N-1)句np.where()
# 对一维ndarray应用np.where()(两种状态)
import numpy as np
a = np.array([10,80,20,90])
b = np.where(a<50)
c = a[np.where(a<50)]
d = np.where(a<50, a, 9999)
print(b,type(b))
print(c,type(c))
print(d,type(d))
执行结果:
(array([0, 2], dtype=int64),) <class 'tuple'>
[10 20] <class 'numpy.ndarray'>
[10 9999 20 9999] <class 'numpy.ndarray'>
# 对一维ndarray应用np.where()(三种状态)
import numpy as np
a = np.array([10,-80,0,-20,90])
b = np.where(a>0, 1, 0)
b = np.where(a<0, -1, b)
print(b,type(b))
执行结果:
[ 1 -1 0 -1 1] <class 'numpy.ndarray'>
# 对二维ndaray应用np.where()(两种状态)
import numpy as np
a = np.array([[66,20,20],
[20,99,20],
[88,77,20]])
b = np.where(a>50)
c = a[np.where(a>50)]
d = np.where(a>50, a, 0)
print(b,type(b))
print(c,type(c))
print(d,type(d))
执行结果:
(array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64)) <class 'tuple'>
[66 99 88 77] <class 'numpy.ndarray'>
[[66 0 0]
[ 0 99 0]
[88 77 0]] <class 'numpy.ndarray'>
# 对二维ndarray应用np.where()(三种状态)
import numpy as np
a = np.array([[66,0,-20],
[-20,99,0],
[0,-77,20]])
b = np.where(a>0, 1, 0)
b = np.where(a<0, -1, b)
print(b,type(b))
执行结果:
[[ 1 0 -1]
[-1 1 0]
[ 0 -1 1]] <class 'numpy.ndarray'>
# x和y都是arr时的情况
import numpy as np
condition = np.array([[True,False],[False,True]])
a = np.array([[1,2],[3,4]])
b = np.array([[50,60],[70,80]])
print(a); print('===========')
print(b); print('===========')
print(np.where(condition, a, b))
执行结果:
[[1 2]
[3 4]]
===========
[[50 60]
[70 80]]
===========
[[ 1 60]
[70 4]]
② np.concatenate()
语法:np.concatenate((arr1, arr2, ...), axis=0)
将若干个ndarray拼接成一个新的ndarray
参数axis:默认值为0,纵向拼接;axis=1时横向拼接
import numpy as np
arr1=np.array([[1, 2],
[3, 4]])
arr2=np.array([[5, 6],
[7, 8]])
arr3=np.array([[9, 10],
[11, 12]])
a = np.concatenate((arr1,arr2,arr3))
b = np.concatenate((arr1,arr2,arr3),axis=1)
print(a); print('===========')
print(b)
执行结果:
[[ 1 2]
[ 3 4]
[ 5 6]
[ 7 8]
[ 9 10]
[11 12]]
===========
[[ 1 2 5 6 9 10]
[ 3 4 7 8 11 12]]
③ np.all()和arr.all()
语法:np.all(arr)
、arr.all()
返回一个布尔值,若arr中所有元素都是True,就返回True,否则返回False
import numpy as np
a = np.array([[0,0],[0,0]])
b = np.array([[0,1],[1,0]])
c = np.array([[1,1],[1,1]])
print(a.all()); print('===========')
print(b.all()); print('===========')
print(c.all())
执行结果:
False
===========
False
===========
True
④ np.any()和arr.any()
语法:np.any(arr)
、arr.any()
返回一个布尔值,只要arr中有一个元素是True,就返回True,否则返回False
import numpy as np
a = np.array([[0,0],[0,0]])
b = np.array([[0,1],[1,0]])
c = np.array([[1,1],[1,1]])
print(a.any()); print('===========')
print(b.any()); print('===========')
print(c.any())
执行结果:
False
===========
True
===========
True
9. NumPy随机数
(1)产生标准正态分布的随机数
① numpy.random.randn()
randn中的n即代表normal
语法:numpy.random.randn(d0,d1,...,dn)
根据给定的维度生成标准正态分布(均值为0,标准差为1)的数据
d0,d1,...,dn是每个维度的值
参数为空时,返回一个float;参数不为空时,返回指定维度的ndarray
② np.random.standard_normal()
语法:np.random.standard_normal(shape)
根据给定的shape生成标准正态分布(均值为0,标准差为1)的数据
参数:
- 默认值为None,此时返回一个float
- shape = 0时,返回一个空的ndarray
- shape是>=1的整数时,返回一个一维的ndarray
- shape是一个元组时,元组中有几个元素就返回几维的ndarray
import numpy as np
random_1d_array = np.random.standard_normal(5) # 一维,长度为5
# random_1d_array = np.random.standard_normal((5,)) # 一维,长度为5,使用元组的表示方法
random_2d_array = np.random.standard_normal((3,4)) # 二维,3行4列
random_3d_array = np.random.standard_normal((2,2,2)) # 三维
print(random_1d_array); print('==================')
print(random_2d_array); print('==================')
print(random_3d_array)
执行结果:
[1.76405235 0.40015721 0.97873798 2.2408932 1.86755799]
==================
[[-0.97727788 0.95008842 -0.15135721 -0.10321885]
[ 0.4105985 0.14404357 1.45427351 0.76103773]
[ 0.12167502 0.44386323 0.33367433 1.49407907]]
==================
[[[-0.20515826 0.3130677 ]
[-0.85409574 -2.55298982]]
[[ 0.6536186 0.8644362 ]
[-0.74216502 2.26975462]]]
③ np.random.normal()
语法:np.random.normal(loc=0.0, scale=1.0, size=None)
根据给定的shape生成均值为loc、标准差为scale的正态分布数据
参数:
- loc:正态分布的均值(float或list)
- scale:正态分布的标准差(float或list)
- size:返回对象的shape
- 默认值为None,此时返回一个float
- size= 0时,返回一个空的ndarray
- size是>=1的整数时,返回一个一维的ndarray
- size是一个元组时,元组中有几个元素就返回几维的ndarray
import numpy as np
random_1d_array = np.random.normal(size=5) # 一维,长度为5
# random_1d_array = np.random.normal(size=(5,)) # 一维,长度为5,使用元组的表示方法
random_2d_array = np.random.normal(size=(3,4)) # 二维,3行4列
random_3d_array = np.random.normal(loc=[1,100000],scale=[1,10000],size=(2,2,2)) # 三维
print(random_1d_array); print('==================')
print(random_2d_array); print('==================')
print(random_3d_array)
执行结果:
[ 1.36942258 -0.34075723 -0.09876788 0.77008845 -1.61318133]
==================
[[ 0.91868812 0.66335297 -0.06814506 -0.2185851 ]
[ 0.54239331 0.85372137 -0.56977034 -0.26731383]
[ 1.8548985 -0.21814791 0.42258236 -0.70729847]]
==================
[[[4.04748732e-01 1.00981797e+05]
[5.70581472e-01 1.03409312e+05]]
[[5.03517513e-01 1.05403085e+05]
[1.52392527e+00 9.90583266e+04]]]
(2)产生均匀分布的随机数
① np.random.rand()
语法:np.random.rand(d0,d1,...,dn)
根据给定的维度生成[0,1)之间均匀分布的数据,包含0,不包含1
d0,d1,...,dn是每个维度的值
参数为空时,返回一个float;参数不为空时,返回指定维度的ndarray
② np.random.random()
语法:np.random.random(shape)
根据给定的shape生成[0,1)之间均匀分布的数据,包含0,不包含1
参数shape:
- 默认值为None,此时返回一个float
- shape = 0时,返回一个空的ndarray
- shape是>=1的整数时,返回一个一维的ndarray
- shape是一个元组时,元组中有几个元素就返回几维的ndarray
③ np.random.uniform()
语法:np.random.uniform(low=0.0, high=1.0, size=None)
根据给定的size生成[low,high)之间均匀分布的数据,包含low,不包含high
参数:
- low:均匀分布的下限(float)
- high:均匀分布的上限(float)
- size:返回对象的shape
- 默认值为None,此时返回一个float
- size= 0时,返回一个空的ndarray
- size是>=1的整数时,返回一个一维的ndarray
- size是一个元组时,元组中有几个元素就返回几维的ndarray
④ np.random.sample()、np.random.random_sample()
语法:np.random.sample(shape)
、np.random.random_sample(shape)
根据给定的shape生成[0,1)之间均匀分布的数据,包含0,不包含1
参数shape:
- 默认值为None,此时返回一个float
- shape = 0时,返回一个空的ndarray
- shape是>=1的整数时,返回一个一维的ndarray
- shape是一个元组时,元组中有几个元素就返回几维的ndarray
(3)产生随机整数 np.random.randint()
语法:np.random.randint(low, high=None, size=None, dtype='l')
其中low为最小值,high为最大值,dtype为数据类型(默认的数据类型是np.int)
生成随机整数的范围区间为[low,high),包含low不包含high,high没有填写时默认生成随机数的范围是[0,low)
参数size:
- 默认值为None,此时返回一个np.int
- size = 0时,返回一个空的ndarray
- size是>=1的整数时,返回一个一维的ndarray
- size是一个元组时,元组中有几个元素就返回几维的ndarray
(4)抽样 np.random.choice()
语法:np.random.choice(a, size=None, replace=True, p=None)
从给定的离散有限数据集中执行若干次抽样(可以是放回抽样,也可以是不放回抽样)
参数:
- a为给定的数据集:
- a为ndarray时,选取此ndarray中的元素执行抽样
- a为list、tuple时,选取里面的元素执行抽样
- a为int时,选取np.arange(a)里面的元素执行抽样,即从0, 1, 2, ..., a-1里抽样
- size为数组维度:
- 默认值为None,此时执行一次抽样,返回元素本身的数据类型(不返回ndarray)
- size = 0时,返回一个空的ndarray
- size是>=1的整数时,返回一个一维的ndarray
- size是一个元组时,元组中有几个元素就返回几维的ndarray
- replace为抽样种类
- 默认值为True,放回抽样
- replace = False时是不放回抽样,此时应确保size大于a中的元素个数,否则报错
- p是a中的元素出现的概率(list形式),默认值为None(均匀分布)
# 例1
import numpy as np
a = np.random.choice(5,20) # 从0,1,2,3,4中抽样,抽20次
print(a)
执行结果:
[1 4 4 1 2 2 1 3 0 4 3 3 2 3 4 4 0 0 3 0]
# 例2
import numpy as np
demo_list = ['python', 'linux','go','c++']
demo_choice = np.random.choice(demo_list, size=(3,5), p=[0.4,0.2,0.1,0.3])
print(demo_choice)
执行结果:
[['linux' 'go' 'linux' 'c++' 'python']
['python' 'c++' 'c++' 'python' 'linux']
['python' 'python' 'c++' 'c++' 'c++']]
(5)随机数种子 np.random.seed()
由于方法每次产生的随机数都不同,不便于对相同数据进行不同算法的比较,可以使用随机数种子来锁定产生的随机数,即每个随机数种子产生的随机数都是相同的
语法:np.random.seed(n=None)
其中n为随机数种子序号,默认值为None(无种子,即每次产生的随机数均不同),n可以取任意一个非负整数,如0、1、2……
np.random.seed(n)应写在py文件中的第一个np.random.xxx之前,它对整个脚本中的np.random.xxx都有效,但是对其他模块的随机数方法无效
只要随机数种子序号相同,且随机数的概率分布相同,即使调用的函数(方法)不同,得到的结果也一定相同,见下面两个例子:
import numpy as np
np.random.seed(0)
a = np.random.standard_normal((2,2)) # standard_normal()方法
print(a)
执行结果:
[[1.76405235 0.40015721]
[0.97873798 2.2408932 ]]
import numpy as np
np.random.seed(0)
b = np.random.randn(2,2) # randn()方法
print(b)
执行结果:
[[1.76405235 0.40015721]
[0.97873798 2.2408932 ]]
10. NumPy线性代数
(1)矩阵及其基本运算方法
① 矩阵的定义
在NumPy中,矩阵是numpy.matrix的实例化对象
由于矩阵本身就是二维的(行、列的概念本身就是建立在二维基础上的,因此行向量、列向量也是二维的)因此矩阵在定义时,np.matrix()里面有且只能有两层中括号[[]]
import numpy as np
# 一行形式
a = np.matrix([[a11,a12,...,a1n],[a21,a22,...,a2n],...,[am1,am2,...,amn]])
# 多行形式
b = np.matrix([
[a11,a12,...,a1n],
[a21,a22,...,a2n],
...,
[am1,am2,...,amn]
])
# 行向量
c = np.matrix([[1,2,3,4,5]])
# c = np.matrix([1,2,3,4,5]) # 这样写也行,但是不规范,NumPy会自动将其解析成两层中括号[[]]
# 列向量
d = np.matrix([[1],[2],[3],[4],[5]])
② 矩阵的乘法
注意:
- 两个矩阵只有满足乘法前提条件(第一个矩阵的列数等于第二个矩阵的行数)时,才能计算它们的乘法,否则会报错
- 只有当a和b都是matrix数据类型时,
a*b
算出来的才是矩阵乘法。如果a和b是ndarray数据类型,那a*b
算出来的是向量化的乘法(元素级别的乘法),此时需要使用np.dot(a,b)或a.dot(b)计算他们的矩阵乘法,详见本章“四.7向量化和广播”
import numpy as np
a = np.matrix([[3, 1], [1, 2]]) # a是2x2矩阵
b = np.matrix([[2],[3]]) # b是2x1矩阵(列向量)
print(a*b)
执行结果: # 得到一个2x1矩阵(列向量)
[[9]
[8]]
③ 矩阵的转置
import numpy as np
b = np.matrix([[2],[3]])
print(b.T)
print('===========')
print(b.transpose())
执行结果:
[[2 3]]
===========
[[2 3]]
(2)求解线性方程
'''
求解线性方程:
3x+y=9
x+2y=8
'''
import numpy as np
a = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])
x = np.linalg.solve(a, b) # linalg是linear algebra(线性代数)的简写
print(x)
执行结果:[2. 3.] # 即x=2、y=3
(3)回归计算
求回归系数除了可以用Numpy的函数以外,用statsmodels或者sk-learn也是可以很快求出来的;但是追根溯源,sk-learn也是用的numpy来求的
① 使用np.polyfit()返回回归系数
语法:np.polyfit(x,y,deg)
返回基于最小二乘法的多项式回归的所有回归系数组成的ndarray(里面有deg+1个回归系数)
参数:
x:自变量序列
y:因变量序列
deg:多项式的次数,必须为int类型
deg=1时为线性回归,y=ax+b,函数返回值为一个ndarray,里面有两项:a,b
import numpy as np
x = np.array([1,2,3,4,5])
y = x * 5 + 2
reg = np.polyfit(x, y ,1)
slope,interception = np.polyfit(x, y ,1)
print(reg,type(reg))
print(slope,interception) 执行结果:
[5. 2.] <class 'numpy.ndarray'>
5.000000000000001 1.999999999999991
deg=2时为二次回归,y=ax**2+bx+c,函数返回值为一个ndarray,里面有三项:a,b,c
import numpy as np
x = np.array([1,2,3,4,5])
y = 8 * x ** 2 - 5 * x - 10
reg = np.polyfit(x, y ,2)
a,b,c = np.polyfit(x, y ,2)
print(reg)
print(a,b,c) 执行结果:
[ 8. -5. -10.]
8.000000000000028 -5.000000000000143 -9.999999999999758
② 使用np.polyval()返回回归的预测结果
语法:np.polyval(回归系数序列,x)
返回基于最小二乘法的多项式回归的预测结果(即返回y的理论值组成的ndarray)
参数:
- 回归系数序列:是一个由回归系数组成的list或一维array,线性回归有两个系数(如
[5,2]
),二次回归有三个系数(如[8,-5,-10]
)……以此类推,n次回归有(n-1)个系数 - x:自变量序列,可以是一个数字或一个序列,返回值的数据结构与x相同
import numpy as np
x = [13,15,12,14]
y_predict = np.polyval([5,2],x) # 有两个回归系数,说明是线性回归
print(y_predict, type(y_predict))
执行结果:
[67 77 62 72] <class 'numpy.ndarray'>
Python数据分析之Numpy操作大全的更多相关文章
- Python数据分析之Pandas操作大全
从头到尾都是手码的,文中的所有示例也都是在Pycharm中运行过的,自己整理笔记的最大好处在于可以按照自己的思路来构建矿建,等到将来在需要的时候能够以最快的速度看懂并应用=_= 注:为方便表述,本章设 ...
- 【Python数据分析】Python3操作Excel(二) 一些问题的解决与优化
继上一篇[Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 对豆瓣图书Top250进行爬取以后,鉴于还有一些问题没有解决,所以进行了进一步的交流讨论,这期间得到了一只尼玛 ...
- Python数据分析(二): Numpy技巧 (1/4)
In [1]: import numpy numpy.__version__ Out[1]: '1.13.1' In [2]: import numpy as np
- Python数据分析(二): Numpy技巧 (2/4)
numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性. 昨天晚上发了第一 ...
- Python数据分析(二): Numpy技巧 (3/4)
numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性. 昨天晚上发了第一 ...
- Python数据分析(二): Numpy技巧 (4/4)
numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性. 第一部分: ht ...
- Python数据分析之numpy学习
Python模块中的numpy,这是一个处理数组的强大模块,而该模块也是其他数据分析模块(如pandas和scipy)的核心. 接下面将从这5个方面来介绍numpy模块的内容: 1)数组的创建 2)有 ...
- (转)Python数据分析之numpy学习
原文:https://www.cnblogs.com/nxld/p/6058572.html https://morvanzhou.github.io/tutorials/data-manipulat ...
- python数据分析工具 | numpy
Python中没有提供数组功能,虽然列表可以完成基本的数组功能,但并不是真正的数组,而且在数据量较大时,使用列表的速度回非常慢.因此,Numpy提供了真正的数组功能,以及对数据进行快速处理的函数.Nu ...
随机推荐
- winform学习(4)控件的添加、显示和隐藏
窗体的添加.显示与隐藏 可以直接通过工具栏将某个控件直接拖动至UI界面(也可以在工具栏里双击某个控件) 也可以在代码里直接添加:窗体的标识.Controls.Add(控件标识符); Button my ...
- 第十篇 深入Python的dict和set(一)
- Mysql sql语句技巧与优化
一.常见sql技巧 1.正则表达式的使用 2.巧用RAND()提取随机行 mysql数据库中有一个随机函数rand()是获取一个0-1之间的数,利用这个函数和order by一起能够吧数据随机排序, ...
- AcWing 867. 分解质因数
#include <iostream> #include <algorithm> using namespace std; void divide(int x) { ; i & ...
- Linux下调试caffe
参考博客:https://blog.csdn.net/xiaoyezi_1834/article/details/50724875 使用Anjuta 我使用的是ubuntu18.04,安装命令: su ...
- TCP和UDP的一些注意事项
TCP的一些注意事项 1. tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器,更无法链接到服务器 2. tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip.port等 ...
- 一段代码实现Aplayer+网易云音乐接口
玩cnblogs的小伙伴可以将以下代码复制到页脚html当中哦 <!-- require APlayer --> <link rel="stylesheet" h ...
- MSComm控件进行串口编程的基本步骤
Visual C++为我们提供了一种好用的ActiveX控件Microsoft Communications Control(即MSComm)来支持应用程序对串口的访问,在应用程序中插入MSComm控 ...
- mybaitis
resultType="java.util.HashMap" SELECT DISTINCT c.COMPANY_LEVEL, ) over ( partition BY COMP ...
- BETWEEN
选取介于两个值之间的数据范围内的值.这些值可以是数值.文本或者日期. 选取 alexa 介于 1 和 20 之间的所有网站: SELECT * FROM table ; NOT BETWEEN 显示不 ...