numpy笔记-ch04:NumPy 基础: Arrays(数组) 和 Vectorized(矢量) 计算
ch04:NumPy 基础: Arrays(数组) 和 Vectorized(矢量) 计算
NumPy 基础: Arrays(数组) 和 Vectorized(矢量) 计算¶
%matplotlib inline
from __future__ import division
from numpy.random import randn
import numpy as np
np.set_printoptions(precision=4, suppress=True)
The NumPy ndarray: 一种多维数组对象¶
记ndarray: Numpy 的 data array(Numpy的数据数组)
'np.random.randn(): 返回标准正太分布'
data = randn(2, 3)
print(data)
print(data * 10)
print(data + data)
print(data.shape,' ' ,data.dtype)
创建ndarrays¶
从序列型对象中(包括其他数组)创建数组¶
'接受一切序列类型的对象:包括数组'
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)
arr1
'接受嵌套序列'
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
print(arr2,'\n',
arr2.ndim,'\n',
arr2.shape)
arr1.dtype
arr2.dtype
从函数中创建数组¶
np.zeros(10)
np.zeros((3,6))
np.empty((4,3,6)) #很多情况下会返回未初始化的垃圾值
np.arange(15)
表4-1:数组创建函数¶
array 将输入数据(列表、元组、数组或其他序列类型)转换为ndarray。要么推断出dtype,要么显式指定dtpye。默认直接复制输入数据 asarray 将输入转换为ndarray,如果输入本身就是一个ndarray就不进行复制 arange 类似于内置的range,但返回的是一个ndarray而不是列表 ones、ones_like 根据指定的形状和dtype创建一个全1数组。ones_like以另一个数组为参数,并根据其形状和dtpye创建一个全1数组 zeros、zeros_like 类似于ones 和 ones_like,只不过产生的是全0数组而已 empty、empty_like 创建新数组,只分配内存空间但不填充任何值 eye、identity 创建一个正方的N*N单位矩阵(对角线为1,其余为0)
ndarrays的数据类型¶
记dtype: data type
arr1 = np.array([1, 2, 3], dtype=np.float64)
arr2 = np.array([1, 2, 3], dtype=np.int32)
arr1.dtype
arr2.dtype
通过astype方法转换dtype¶
'整数转换成浮点数'
arr = np.array([1, 2, 3, 4, 5])
arr.dtype
float_arr = arr.astype(np.float64) #整数转换成浮点数
float_arr.dtype
'浮点数转换成整数,小数部分会被截断'
arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
arr
arr.astype(np.int32)
'字符串数组全部是数字的话可以转化成数值形式:否则会抛出TypeError异常'
numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
numeric_strings.astype(float)
'转换成另一个数组的 dtype'
int_array = np.arange(10)
calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64)
int_array.astype(calibers.dtype)
'简洁类型代码表示 dtype'
empty_uint32 = np.empty(8, dtype='u4')
empty_uint32
表4-2:Numpy的数据类型¶
类型 类型代码 说明 int8、uint8 i1、u1 有符号和无符号的8位(1个字节)整型 int16、uint16 i2、u2 有符号和无符号的16位(2个字节)整型 int32、uint32 i3、u3 有符号和无符号的32位(4个字节)整型 int64、uint64 i4、u4 有符号和无符号的64位(8个字节)整型 float16 f2 半精度浮点数 float32 f4或f 标准的单精度浮点数。与C的float兼容 float64 f8或d 标准的双精度浮点数。与C的double和Python的float对象兼容 float128 f16或g 扩展精度浮点数 complex64、complex128、complex256 c8或c16或c32 分别用两个32位、64位或128位浮点数表示的复数 bool ? 存储True和False值的布尔类型 object O Python对象类型 string_ S 固定长度的字符串类型(每个字符1个字节)。例如,要创建一个长度为10的字符串,应使用S10 unicode_ U 固定长度的Unicode类型(字节数由平台决定)。跟字符串的定义方式一样(如U10)
数组和标量之间的运算¶
'大小相等的数组之间的任何运算都会将运算应用到元素级'
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
arr
arr * arr
arr - arr
'数组与标量之间的运算也是元素级别的运算'
1 / arr
arr ** 0.5
基本的索引和切片¶
arr = np.arange(10)
arr
arr[5]
arr[5:8]
'通过切片赋值修改数组'
arr[5:8] = 12
arr
'切片传递的是指针,对切片传递的数组修改会影响到原数组'
arr_slice = arr[5:8]
arr_slice[1] = 12345
arr
arr_slice[:] = 64
arr
'高维数组的索引'
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
#一下两种方式索引等价
arr2d[0][2]
arr2d[0, 2]
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr3d
arr3d[0]
'标量值和数组都可以被赋值给arr3d[0]'
old_values = arr3d[0].copy()
arr3d[0] = 42
arr3d
arr3d[0] = old_values
arr3d
arr3d[1, 0]
切片索引¶
'数组的切片语法类似于Python的列表'
arr[1:6]
arr2d
'默认第一个轴切片'
arr2d[:2]
'两个轴:同时切片'
arr2d[:2, 1:]
arr2d[:, :1]
'两个轴:索引与切片混合'
arr2d[1, :2]
arr2d[2, :1]
'切片赋值'
arr2d[:2, 1:] = 0
arr2d
布尔型索引¶
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = randn(7, 4)
names
data
'数组的比较运算也是矢量化的(即运算到元素)'
names == 'Bob'
'布尔型索引'
data[names == 'Bob']
'布尔型索引与切片或索引混合'
data[names == 'Bob', 2:]
data[names == 'Bob', 3]
'!= 与 -'
names != 'Bob'
data[-(names == 'Bob')] # - 过时 请使用 ~ 或者 logical_not function
data[~(names == 'Bob')] # - 过时 请使用 ~ 或者 logical_not function
data[(names != 'Bob')] # - 过时 请使用 ~ 或者 logical_not function
mask = (names == 'Bob') | (names == 'Will')
mask
data[mask]
'布尔类型索引赋值'
data[data < 0] = 0
data
data[names != 'Joe'] = 7
data
花式索引:利用整数数组进行索引¶
注:花式索引传递的不是指针,而是复制,注意这点与切片的不同
arr = np.empty((8, 4))
for i in range(8):
arr[i] = i
arr
arr[[4, 3, 0, 6]]
arr[[-3, -5, -7]]
# more on reshape in Chapter 12
arr = np.arange(32).reshape((8, 4))
arr
'花式多维索引对应具体值,非区域'
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
'单维索引 + 切片:获取一个区域'
arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
'利用函数 ix_ 通过索引获取区域值'
arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])]
转置和轴对换¶
arr = np.arange(15).reshape((3, 5))
arr
arr.T # arr转置
arr = np.random.randn(6, 3)
np.dot(arr.T, arr) # dot 计算矩阵内积 arr.T * arrr
arr = np.arange(16).reshape((2, 2, 4))
arr
arr.transpose((1, 0, 2)) # 1, 0, 2 是轴编号
arr
arr.swapaxes(1, 2) #特定轴进行转置,接受轴编号
通用函数:快速的元素级数组函数¶
'一元ufunc举例'
arr = np.arange(10)
np.sqrt(arr)
np.exp(arr)
'二元ufunc举例'
x = randn(8)
y = randn(8)
x
y
np.maximum(x, y) # element-wise maximum
'返回多个数组的ufunc举例'
arr = randn(7) * 5
arr
'np.modf(): python内置函数divmod的矢量化版本'
np.modf(arr)
表4-3:一元ufunc(类方法,非实例化方法)简介:¶
abs、fabs 计算整数、浮点数或复数的绝对值。对于非复数值,可以使用更快的fabs sqrt 计算各元素的平方根。相当于arr**0.5 square 计算各元素的平方。相当于arr**2 exp 计算各元素的指数e^x log,log10,log2,log1p 分别计算自然对数(底数为e),地数为10的log,底数为2的log,ln(1+x) sign 计算各元素的正负号:1(正数)、0(零)、-1(负数) ceil 计算各元素的ceiling值,即大于等于该值的最小整数 floor 计算个元素的floor值,级小于等于该值的最大整数 rint 将各元素值四舍五入到最接近的整数,保留dtype modf 将数组的小数和整数部分以两个独立数组的形式返回 isnan 返回布尔型数组 isfinite,isinf 分别返回一个表示‘哪些元素是有穷的(非inf,非NaN)’或‘哪些元素是无穷的’的布尔型数组 cos,cosh,sin,sinh,tan,tanh 普通型和双曲线型三角函数 arccos,arccosh,arcsin,arcsinh,arctan,arctanh 反三角函数 logical_not 计算各元素not x 的真值。相当于 -arr
表4-4:二元unfunc的简介:¶
add 将数组中对应的元素相加 subtract 从第一个数组中减去第二个数组中的元素 multiply 数组元素相乘 divide,floor_divide 除法或向下圆整除法(丢弃余数) power 对第一个数组中的元素A,根据第二个数组中的相应元素B,计算A\*\*B maximum,fmax 元素级的最大值计算,fmax将忽略NaN minimum,fmin 元素级的最小值计算。fmin将忽略NaN mod 元素级的求模计算(除法的余数) copysign 将第二个数组中的值的符号复制给第一个数组中的值 greater,greater_equal,less,less_equal,equal,not_equal 执行元素级的比较运算,最终产生布尔型数组。相当于中缀运算符>,>=,<,<=,==,!= logical_and,logical_or,logical_xor 执行元素级的真值逻辑运算。相当于中缀运算符&,|,^
利用数组进行数据处理¶
points = np.arange(-5, 5, 0.01) # 1000 equally spaced points
'xs,ys是1000*1000的矩阵'
xs, ys = np.meshgrid(points, points)
xs.T == ys
ys
xs
from matplotlib.pyplot import imshow, title
import matplotlib.pyplot as plt
z = np.sqrt(xs ** 2 + ys ** 2)
z
%matplotlib inline
plt.imshow(z, cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
%matplotlib notebook
plt.plot()
plt.imshow(z, cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
plt.draw() #redraw 功能,适用于已经更新了数据,但是没有更新图像的功能
将条件逻辑表述为数组运算¶
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
'纯Python的三元表达式'
result = [(x if c else y)
for x, y, c in zip(xarr, yarr, cond)]
result
#纯Python完成的两个缺陷:
# 1.运算速度慢
# 2.无法适用于多维数组
'np.where运算:第二个和低三个不必是数组,也可以是表达式'
result = np.where(cond, xarr*10, yarr)
result
arr = randn(4, 4)
arr
np.where(arr > 0, 2, -2) # arr 所有正值替换为 2,所有负值替换为 -2
np.where(arr > 0, 2, arr) # 仅仅设置正值为 2
# Not to be executed
result = []
for i in range(n):
if cond1[i] and cond2[i]:
result.append(0)
elif cond1[i]:
result.append(1)
elif cond2[i]:
result.append(2)
else:
result.append(3)
'上面for循环可以改写成:'
np.where(cond1 & cond2, 0,
np.where(cond1, 1,
np.where(cond2, 2, 3)))
'也可以改写成:'
result = 1 * cond1 + 2 * cond2 + 3 * -(cond1 | cond2)
数学和统计方法¶
'聚合性:返回结果为标量,包括实例化调用和顶级Numpy数组的调用两种调用方法'
arr = np.random.randn(5, 4) # normally-distributed data
arr.mean() #实例化调用
np.mean(arr) #顶级Numpy数组调用:两者结果一致
arr
arr.sum()
# '对 轴 进行数学运算'
arr.mean(axis=1)
arr.sum(0) #arr.sum(axis=0)
'非聚合性:返回数组,如累计计算'
arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr.cumsum(0) #累计加
arr.cumprod(1) #累计乘
表4-5:基本数组统计方法(实例化方法+顶级Numpy方法):¶
sum 对数组中全部或某轴向的元素求和。零长度的数组的sum为0 mean 算术平均数。零长度的数组的mean为NaN std,var 分别为标准差和方差,自由度可调(默认为n) min,max 最大值和最小值 argmin,argmax 分别为最大和最小元素的索引 cumsum 所有元素的累计和 cumprod 所有元素的累计积
布尔型数组的方法¶
arr = randn(100)
arr>0
(arr > 0).sum() # 正值的个数
bools = np.array([False, False, True, False])
bools.any()
bools.all()
排序¶
arr = randn(8)
arr
arr2 = randn(8)
arr2
'实例化排序改变原始数组'
arr.sort()
arr
'顶层排序np.sort是返回排序后的副本'
print(np.sort(arr2))
print(arr2)
'多维数组排序'
arr = randn(5, 3)
arr
arr.sort(1)
arr
'简单的计算数组分位数的方法'
large_arr = randn(100)
large_arr.sort()
large_arr
large_arr[int(0.05 * len(large_arr))] # 5% quantile
唯一化以及其他的集合逻辑¶
'np.unique:返回数组集合后的排序'
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
np.unique(names)
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
np.unique(ints)
'等价的Python代码:'
sorted(set(names))
'np.inld:成员资格测试'
values = np.array([6, 0, 0, 3, 2, 5, 6])
np.in1d(values, [2, 3, 6])
表4-6 数组的集合运算¶
unique(x) 计算x中的唯一元素,并返回有序结果 intersect1d(x,y) 计算x和y的公共元素,并返回有序结果 union1d(x,y) 计算x和y的并集,并返回有序结果 in1d(x,y) 得到一个表示‘x的元素是否包含于y’的布尔型数组 setdiff(x,y) 集合的差,级元素在x中且不在y中 setxor1d(x,y) 集合的对称差,即存在于一个数组中但不同时存在两个数组中的元素
数组的文件输入和输出¶
以二进制格式存储数组到硬盘 np.save, np.savez, np.load¶
arr = np.arange(10)
np.save('some_array', arr) # 会自动添加 .npy 后缀
np.load('some_array.npy')
'保存多个数组 .npz'
np.savez('array_archive.npz', a=arr, b=arr)
'读取 .npz 格式:类似字典的形式访问。'
arch = np.load('array_archive.npz')
arch['b']
!del some_array.npy
!del array_archive.npz
存取文本文件¶
np.savetxt('ex3.txt', randn(4,5), delimiter=',')
!type ex3.txt
arr = np.loadtxt('ex3.txt', delimiter=',')
arr
线性代数¶
x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
x
y
x.dot(y) # 等于 np.dot(x, y)
np.dot(x, np.ones(3))
np.random.seed(12345)
from numpy.linalg import inv, qr
X = randn(5, 5)
mat = X.T.dot(X)
inv(mat)
mat.dot(inv(mat))
q, r = qr(mat)
r
表4-7:常用的numpy.linalg函数¶
diag 以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0) dot 矩阵乘法 trace 计算对角线元素之和 det 计算矩阵行列式 eig 计算方针的特征值和特征向量 inv 计算方阵的逆 pinv 计算矩阵的Moore-Penrose伪逆 qr 计算QR分解 svd 计算奇异值分解(SVD) solve 解线性方程组Ax=b,其中A为一个方阵 lstsq 计算Ax=b的最小二乘解
随机数生成¶
samples = np.random.normal(size=(4, 4))
samples
from random import normalvariate
N = 1000000
%timeit samples = [normalvariate(0, 1) for i in range(N)]
'np.random比Python内置的random模块运行速度快'
%timeit np.random.normal(size=N)
表4-8:部分numpy.random函数¶
seed 确定随机数数生成器的种子 permutation 返回一个序列的随机排列或返回一个随机排列的范围 shuffle 对一个序列就地随机排列 rand 产生均匀分布的样本值 randint 从给定的上下限范围内随机选取整数 randn 产生正态分布(平均值为0,标准差为1)的样本值,类似于MATLAB接口 binomial 产生二项分布的样本值 normal 产生正态分布(高斯分布)的样本值 beta 产生beta分布的样本值 chisquare 产生卡方分布的样本值 gamma 产生Gamma分布的样本值 uniform 产生在[0,1)中均匀分布的样本值
随机漫步的案例¶
import matplotlib as plt
import random
position = 0
walk = [position]
steps = 1000
for i in range(steps):
step = 1 if random.randint(0, 1) else -1
position += step
walk.append(position)
np.random.seed(12345)
'np.random的随机漫步等价形式'
nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum()
walk.min()
walk.max()
'本次随机漫步多久才能举例初始点10个位置:(第一个True就是最大值)'
(np.abs(walk) >= 10).argmax() #np.argmax :返回某一轴上最大值的索引,不选择轴则默认以一维数组处理
一次模拟多个随机漫步¶
nwalks = 5000
nsteps = 1000
draws = np.random.randint(0, 2, size=(nwalks, nsteps)) # 0 or 1
steps = np.where(draws > 0, 1, -1)
walks = steps.cumsum(1)
walks
walks.max()
walks.min()
'计算30或-30的最小穿越时间'
hits30 = (np.abs(walks) >= 30).any(1)
hits30
hits30.sum() # Number that hit 30 or -30
'穿越30所走的步数的集合'
crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1)
crossing_times
crossing_times.mean()
'其他方式获得漫步数据:如normal获得指定均值和标准差的正态分布数据'
steps = np.random.normal(loc=0, scale=0.25,
size=(nwalks, nsteps))
steps

浙公网安备 33010602011771号