从头到尾都是手码的,文中的所有示例也都是在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.Tarr.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操作大全的更多相关文章

  1. Python数据分析之Pandas操作大全

    从头到尾都是手码的,文中的所有示例也都是在Pycharm中运行过的,自己整理笔记的最大好处在于可以按照自己的思路来构建矿建,等到将来在需要的时候能够以最快的速度看懂并应用=_= 注:为方便表述,本章设 ...

  2. 【Python数据分析】Python3操作Excel(二) 一些问题的解决与优化

    继上一篇[Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 对豆瓣图书Top250进行爬取以后,鉴于还有一些问题没有解决,所以进行了进一步的交流讨论,这期间得到了一只尼玛 ...

  3. Python数据分析(二): Numpy技巧 (1/4)

    In [1]: import numpy numpy.__version__ Out[1]: '1.13.1' In [2]: import numpy as np  

  4. Python数据分析(二): Numpy技巧 (2/4)

    numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性.   昨天晚上发了第一 ...

  5. Python数据分析(二): Numpy技巧 (3/4)

    numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性.   昨天晚上发了第一 ...

  6. Python数据分析(二): Numpy技巧 (4/4)

    numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性.   第一部分: ht ...

  7. Python数据分析之numpy学习

    Python模块中的numpy,这是一个处理数组的强大模块,而该模块也是其他数据分析模块(如pandas和scipy)的核心. 接下面将从这5个方面来介绍numpy模块的内容: 1)数组的创建 2)有 ...

  8. (转)Python数据分析之numpy学习

    原文:https://www.cnblogs.com/nxld/p/6058572.html https://morvanzhou.github.io/tutorials/data-manipulat ...

  9. python数据分析工具 | numpy

    Python中没有提供数组功能,虽然列表可以完成基本的数组功能,但并不是真正的数组,而且在数据量较大时,使用列表的速度回非常慢.因此,Numpy提供了真正的数组功能,以及对数据进行快速处理的函数.Nu ...

随机推荐

  1. HTML学习(16)颜色

    HTML 颜色由红色.绿色.蓝色混合而成. 颜色值 HTML 颜色由一个十六进制符号来定义,这个符号由红色.绿色和蓝色的值组成(RGB). 每种颜色的最小值是0(十六进制:#00).最大值是255(十 ...

  2. Rabbitmq consumer端超时报错

    0x01 应用场景: 使用rabbitmq的exchange模式,type为direct,消费端不需要向生产端返回结果no_ack=True 其中某个consumer任务耗时较长(5min以上),结果 ...

  3. java项目连接Oracle配置文件

    转载自:https://blog.csdn.net/shijing266/article/details/42527471 driverClassName=oracle.jdbc.driver.Ora ...

  4. UC972开发板,参考实验8,完成定时器触发信号输出实验

    代码 ETIMER0 TGL --> PB2 #include "nuc970.h" #include "sys.h" #include "et ...

  5. Linux - 命令 - 查找命令总结

    关于查找文件的几个命令 一.find命令 find是最常用也是最强大的查找命令,可以查找任何类型的文件 find命令的一般格式: find <指定目录><指定条件><指定 ...

  6. Type Java类型

    参考:https://blog.csdn.net/a327369238/article/details/52621043 Type —— Java类型 Type是一个空接口,所有类型的公共接口(父接口 ...

  7. wampserver 配置的几个坑(雾

    1. 从安装版本说起 自从我进入大学之后,便继承了学长那里的wampserver2.5版本 直到有一天自己下载wamp的时候才注意到已经有 3.0.6版本了 (现在有更高的了 但是3.0.6够用了) ...

  8. 吴裕雄 python 机器学习——集成学习AdaBoost算法分类模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...

  9. 吴裕雄 python 机器学习——支持向量机线性分类LinearSVC模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets, linear_model,svm fr ...

  10. wix中ServiceInstall与ServiceControl的关系

    上面那篇之后其实还踩了个坑,安装Windows服务确实是打包进去了,但死活不能安装成功,从提示和日志看正好是Windows服务处理的地方出现了异常.以为是服务启动失败,但是服务在服务管理里手动启动是没 ...