Numpy读书笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GodsLeft/article/details/50913297

ndarray 多维数组对象

创建ndarray

# 列表转换
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)

# 嵌套序列
data2 = [[1,2,3,4],[5,6,7,8]]
arr2 = np.array(data2)

# 其他创建数组的函数
np.zeros(10)
np.zeros((3,6))
np.empty((2,3,2)) #返回的是未初始化的值,非零
np.arange(15)
...

ndarray的数据类型

# 创建的时候指定类型
arr1 = np.array([1,2,3], dtype=np.float64) #双精度浮点
arr2 = np.array([1,2,3], dtype=np.int32)

# 使用ndarray的astype显示转换类型,任何时候使用astype会创建新数组
arr = np.array([1,2,3,4,5,6])
arr.dtype
float_arr = arr.astype(np.float64)

# 如果字符串数组全部表示的是数字,可转
num_strings = np.array(['1.25','-9.6','42'],dtype=np.string_)
num_strings.astype(float)

数组和标量之间的运算

# 大小相等的数组之间的任何算术运算都会应用到元素级别
arr = np.array([[1,2,3],[4,5,6]])
arr_pow = arr*arr

# 数组与标量运算
1/arr
arr*0.5

基本的索引和切片

arr = np.array(10)
arr[5]
arr[5:8]
# 将一个标量赋值给一个切片时,该值自动广播到整个选区
arr[5:8] = 12

# 跟列表的区别:数组切片是原始数组的视图,不会被复制,修改反应到源数组
arr_slice = arr[5:8]
arr_slice[1] = 12345

# 如果想要得到ndarray切片的一份副本,需要显示调用
arr[5:8].copy()

# 对于2维数组
arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
arr2d[2]
arr2d[0][2] <=> arr2d[0,2]

# 对于多维,要明白2*2*3:表示2个2*3
arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
old_values = arr3d[0]
arr3d[0] = 24          #标量赋值
arr3d[0] = old_values
arr3d[1,0]

#########################################
# 重要区别
arr2d[:,0]   #混合了整数索引和切片,得到的是低维度的切片
arr2d[:,:1]  #

布尔索引

# !!!通过布尔索引选取数组中的数据,将总是创建数据的副本!!!
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Jow'])
data = randn(7,4)

# 布尔型数组的长度必须和被索引的轴长度一致
data[names == 'Bob']

# 可结合布尔运算符使用 ~ & | !!! and or 在这里无效
data[(names == 'Bob') | (names == 'Will')]

# 将data中所有负值设为0
data[data < 0] = 0

# 设置整行或者整列的值
data[names != 'Joe'] = 7

花式索引

# 指的是使用整数数组进行索引,总将数据复制到新数组中
arr= np.empty((8,4))
for i in range(8):
    arr[i] = i

# 传入整数列表,或者ndarray数组
arr[[4,3,0,6]]

# 传入多个索引数组,体会区别
arr = np.arange(32).reshape((8, 4))
arr[[1,5,7,2], [0,3,1,2]]
arr[[1,5,7,2]][:,[0,3,1,2]]
arr[np.ix_([1,5,7,2],[0,3,1,2])]

数组转置和轴对换

# 该类操作返回源数据视图,不进行复制操作
arr = np.arange(15).reshape((3,5))
# 简单转置
arr.T

# 对于高维数组,使用transpose需要得到一个由轴编号组成的元组
arr = np.arange(16).reshape((2,2,4))
arr.transpose((1,0,2))

# 还可使用np.swapaxes函数
arr.swapaxes(1,2)

通用函数

# 对ndarray中的数据执行元素级运算
arr = np.arange(10)

# 一元 ufunc
np.sqrt(arr)
np.exp(arr)

# 二元 ufunc
x = randn(8)
y = randn(8)
np.maximum(x, y)
...

利用数组进行数据处理

import matplotlib.pyplot as plt
points = np.arange(-5,5,0.01)
xs, ys = np.meshgrid(points, points)
z = np.sqrt(xs**2 + ys**2)
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.show()

将条件逻辑表述为数组运算

# numpy.where 是三元表达式 x if condition else y 的矢量版本
xarr = np.array([1.0,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])

result = [(x if c else y) for x,y,c in zip(xarr,yarr,cond)]
result = np.where(cond, xarr, yarr)

arr = randn(4, 4)
np.where(arr>0, 2, -2)
np.where(arr>0, 2, arr) # 只将正值设为2

数学和统计方法

# 大部分既可以当做数组方法调用,也可以作为顶级Numpy函数
arr = np.random.randn(5,4)
arr.mean()
np.mean(arr)
arr.sum()

# 接收一个axis参数, 1代表行, 0代表列
arr.mean(axis = 1)
arr.cumsum()    #累计和
arr.cumprod()   #累计积

用于布尔数组的方法

# 对于上面的计算,布尔值会被强制转换为1或0
arr = randn(100)
(arr>0).sum()

# any 和 all
bools = np.array([False, False, True, False])
bools.any() #是否有True
bools.all() #是否全部True

排序

# Numpy数组可以通过sort就地排序,会修改源数据
arr = randn(8)
arr.sort()

# 多维数组
arr = randn(5, 3)
arr.sort(1)

# np.sort 返回的是已排序的副本
# 计算分位数
large_arr = randn(1000)
large_arr.sort()
large_arr[int(0.05 * len(large_arr))]

唯一化以及其他的集合逻辑

# 针对一维ndarray的基本集合运算。
names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
np.unique(names)

# np.in1d 测试数组中的值在另一个数组中的成员资格
values = np.array([6,0,0,3,2,5,6])
np.in1d(values, [2,3,6])

# 其他操作
intersect1d
union1d
setdiff1d
setxorf1d

用于数组文件的输入输出

将数组以二进制格式保存到磁盘

# 默认情况下,是以未压缩的原始二进制格式保存在扩展名为.npy的文件中
arr = np.arange(10)
np.save('some_array', arr)

# 加载
np.load('some_array')

# 将多个数组保存在一个压缩文件中
np.savez('array_achive.npz', a=arr, b=arr)
# 加载.npz文件时,会得到一个字典对象,该对象会对各个数组进行延迟加载
arch = np.load('array_achive.npz')
arch['b']

存取文本文件

# np.loadtxt, np.genfromtxt
arr = np.loadtxt('array_ex.txt', delimiter=',')
np.savetxt('arr', arr, delimiter=',')

# 关于数据加载可以使用pandas的read_csv,read_table

线性代数

# 矩阵乘法
x = np.array([[1,2,3],[4,5,6]])
y = np.array([[6,23],[-1,7],[8,9]])
x.dot(y)
np.dot(x, y)

# numpy.linalg中有一组标准的矩阵分解运算以及诸如求逆和行列式之类的东西,使用的行业标准级Fortran库,如BLAS, LAPACK,Intel MKL
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)

随机数生成

# 生成大量样本值numpy.random很快
# 标准正太分布
samples = np.random.normal(size=(4,4))

# 部分numpy.random函数
seed            #随机数生成器的种子
permutation     #返回一个序列的随机排列
shuffle         #对一个序列就地随机排列
rand            #产生均匀分布的样本值
randint         #从给定的上下限范围内随机选取整数
randn           #产生正太分布
binomial        #产生二项分布的样本值
normal          #正太分布
beta            #Beta分布样本值
chisquare       #产生卡方分布的样本值
uniform         #产生[0,1)中均匀分布的样本值

随机漫步

import random
position = 0
walk = [position]
steps = 1000
for i in xrange(steps):
    step = 1 if random.randint(0,1) else -1
    position += step
    walk.append(position)

# 另一种写法
import numpy as np
nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws>0, 1, -1)
walk = steps.cumsum()

# 获得第1个10或者-10的索引
(np.abs(walk) >= 10).argmax()

# 一次多个(5000)随机漫步
nwalks = 5000
nsteps = 1000
draws = np.random.randint(0,2,size=(nwalks, nsteps))
steps = np.where(draws>0, 1, -1)
walks = steps.cumsum(1)
# 随机漫步过程的最大最小值
walks.max()
walks.min()
# 计算30或-30的最小穿越时间
hist30 = (np.abs(walks) >= 30).any(1)
hist30.sum()
crossing_times = (np.abs(walks[hist30]) >= 30).argmax(1)
crossing_times.mean()

没有更多推荐了,返回首页