您的位置:首页 > 编程语言 > Python开发

Numpy学习笔记

2016-12-29 10:10 344 查看
基于Wes McKinney的Python for Data Analysis第四章NumPy Basics: Arrays and Vectorized Computation整理代码得来。

最近在自学Python,感觉还是要敲一下的,又懒得在书上做笔记,所以在Notebook上写写喽。
有需要的尽管参考~谢谢

import numpy as np

#通过np.array()用list创建一维数组
#list是用[]括起来的,元素之间用逗号
data1 = [6,7.5,8,0,1]
arr1 = np.array(data1)
print arr1
type(data1)

[ 6.   7.5  8.   0.   1. ]
list

#通过np.array()用list创建二维数组
#list是用[]括起来的,每行是一个[],不同行之间用逗号

data2 = [[1,2,3,4],[5,6,7,8]]
arr2 = np.array(data2)
print arr2
[[1 2 3 4]
[5 6 7 8]]
#查看数组的位数和形状以及数据类型
print arr2.shape
print arr2.ndim
print arr1.dtype
print arr2.dtype

(2, 4)
2
float64
int64


#可以通过制定dtype来强制显性规定数组内元素的数据类型

#可以用过np.asdtype来转换ndarray里面的元素的数据类型,如果非数字类型的list强制转化会报错
"""
通过numpy的函数来新建数组
"""

print '全是0的五位数组:',np.zeros(5)
print '全是1的五维数组:',np.ones(5)
print '全是0的3*3数组:',np.zeros((3,3))
print '全是1的3*3数组:',np.ones((3,3))
print '全是1的3*3*3数组:',np.ones((2,2,2))
print np.empty((3,3))
print np.ones_like(arr2)#生成一个维度如同括号内数组的全是0的数组,传入的参数为ndarry格式
print np.zeros_like(arr2)
print np.eye(3)#产生单位矩阵,输入参数为阶数
print np.arange(10)
print np.arange(1,10,2)#np.arange(开始,结束,步长),其中开始可以省略(默认为0)步长可以省略(默认为1)
#如果想产生从大到小的数组可以通过如下的方式产生
print np.arange(10,0,-1)

全是0的五位数组: [ 0.  0.  0.  0.  0.]
全是1的五维数组: [ 1.  1.  1.  1.  1.]
全是0的3*3数组: [[ 0.  0.  0.]
[ 0.  0.  0.]
[ 0.  0.  0.]]
全是1的3*3数组: [[ 1.  1.  1.]
[ 1.  1.  1.]
[ 1.  1.  1.]]
全是1的3*3*3数组: [[[ 1.  1.]
[ 1.  1.]]

[[ 1.  1.]
[ 1.  1.]]]
[[ 1.  1.  1.]
[ 1.  1.  1.]
[ 1.  1.  1.]]
[[1 1 1 1]
[1 1 1 1]]
[[0 0 0 0]
[0 0 0 0]]
[[ 1.  0.  0.]
[ 0.  1.  0.]
[ 0.  0.  1.]]
[0 1 2 3 4 5 6 7 8 9]
[1 3 5 7 9]
[10  9  8  7  6  5  4  3  2  1]

'''
数组的运算
'''
arr = np.array([[1.,2.,3.],[4.,5.,6.]])
print("The square of arr is :",arr*arr)
print("1/arr = ",1/arr)
print("arr-arr:",arr-arr)
print("A half of arr is :",arr*0.5)
('The square of arr is :', array([[  1.,   4.,   9.],
[ 16.,  25.,  36.]]))
('1/arr = ', array([[ 1.        ,  0.5       ,  0.33333333],
[ 0.25      ,  0.2       ,  0.16666667]]))
('arr-arr:', array([[ 0.,  0.,  0.],
[ 0.,  0.,  0.]]))
('A half of arr is :', array([[ 0.5,  1. ,  1.5],
[ 2. ,  2.5,  3. ]]))

'''
切片和索引:一维数组
'''
#np.arange()函数是range内置函数的array版本
arr1 = np.arange(10)
print arr1
#同list的切片,index从0开始,arr[i]就是第i+1个元素
print arr1[5]
#这个就尴尬了,arr[i:j]表示从第i+1个元素开始向后数j-i个元素拿出来
print arr1[5:8]
#ndarray作为迭代器iterator
for i in arr1:
arr1[i]=10-i

print arr1

#切片后的部分还是原来array的一部分,如果对切片进行修改的话会影响到原有的array的
#如果希望将切片后的array单独保存,可以使用array[].copy()

[0 1 2 3 4 5 6 7 8 9]
5
[5 6 7]
[10  9  8  7  6  5  4  3  2  1]
'''
切片和索引:高维数组
'''
arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])#小括号里有两层中括号
print arr2d

print arr2d[0][2]#等价于arr2d[0,2]

arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print
print arr3d
print
print arr3d[0]#三维数组的一个切片是一个二维数组
[[1 2 3]
[4 5 6]
[7 8 9]]
3

[[[ 1  2  3]
[ 4  5  6]]

[[ 7  8  9]
[10 11 12]]]

[[1 2 3]
[4 5 6]]

#二维的array的切片如果仅仅有一个维度默认的是行向切片的,而且[:2]等价于[0:2]
print arr2d[:2]
#如果切片传入两个参数,第一个参数从行向切片,第二个从列向切片。最后切出来是个矩阵
print arr2d[:2,1:]
print arr2d[:,:1]

[[1 2 3]
[4 5 6]]
[[2 3]
[5 6]]
[[1]
[4]
[7]]

#Bool型索引
names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
data = np.random.randn(7,4)
names == 'Bob'
#利用Bool数组对array进行切片,最后切出来的是第一行和第四行,因为只有这两行的Bool值为True
#Bools的维度和array的需要切片的维度要相同,
data[names == 'Bob']
data[-(names == 'Bob')]
#Bool值里面的逻辑运算 |或 &且 !=非 或者直接在前面加负号
mask = (names == 'Bob')|(names == 'Will')
data[mask]

data[data<0] = 0
print data

[[ 1.73468624  0.03652492  1.01359411  0.95894325]
[ 0.24481808  0.10041709  0.          0.        ]
[ 0.          0.99979847  0.          0.37789161]
[ 0.24150958  0.75716877  0.          0.        ]
[ 0.47633598  0.22929087  0.          0.91475764]
[ 0.          0.          0.45932134  0.26343811]
[ 0.80821826  0.          0.          0.        ]]

#Fancy Indexing
arr2 = np.empty((8,4))
for i in range(8):
arr2[i] = i

print arr2
#传入的list相当于给了一个顺序,指定切出array里面的第几行并按照list的顺序排列,如果list里面给的是负数,就从后往前数
arr2[[4,3,0,6]]
arr2[[-3,-5,-7]]

[[ 0.  0.  0.  0.]
[ 1.  1.  1.  1.]
[ 2.  2.  2.  2.]
[ 3.  3.  3.  3.]
[ 4.  4.  4.  4.]
[ 5.  5.  5.  5.]
[ 6.  6.  6.  6.]
[ 7.  7.  7.  7.]]
array([[ 5.,  5.,  5.,  5.],
[ 3.,  3.,  3.,  3.],
[ 1.,  1.,  1.,  1.]])

#Fancy Indexing 2
print "输出的是(1,0),(5,3)上面的元素"
print arrr[[1,5,7,2],[0,3,1,2]]
print "输出的是行列index交叉以后的元素,可以构成一个矩阵"
print arrr[[1,5,7,2]][:,[0,3,1,2]]
print "同上面的方法,用np.ix_函数"
print arrr[np.ix_([1,5,7,2],[0,3,1,2])]

输出的是(1,0),(5,3)上面的元素
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<mercury-input-12-DD1667028419416A87EC6CDDAC3F1604> in <module>()
1 #Fancy Indexing 2
2 print "输出的是(1,0),(5,3)上面的元素"
----> 3 print arrr[[1,5,7,2],[0,3,1,2]]
4 print "输出的是行列index交叉以后的元素,可以构成一个矩阵"
5 print arrr[[1,5,7,2]][:,[0,3,1,2]]

NameError: name 'arrr' is not defined
#数组transpose等等
arrrr = np.arange(15).reshape((3,5))
print arrrr
print "After transpose:"
print arrrr.T
print "内积的计算"
print np.dot(arrrr.T,arrrr)
#同时转置也可以用swapaxes函数
print "用swapaxes进行二维数组的转置"
print arrrr.swapaxes(1,1)

#Numpy里的通用函数
ar = np.arange(10)
print "平方根",np.sqrt(ar)
print "自然对数",np.exp(ar)
x = np.random.randn(8)
y = np.random.randn(8)
print "x=",x
print "y=",y
print "同位置元素最大的构成的array",np.maximum(x,y)
print "np.modf用于返回一个array的整数部分和小数部分,返回两个数组",np.modf(x)
print np.power(x,y)#相当于x的y次方
print np.add(x,y)#加法的array版本
print np.subtract(x,y)#减法的array版本
print np.multiply(x,y)#乘法的array版本
print np.divide(x,y)#除法的array版本
print np.floor_divide(x,y)#丢弃余数的除法
#此外还有一系列比较大小的运算函数,此外还有np.logical系列用于逻辑运算

#利用array进行数据处理
points = np.arange(15,5,0.01)
xs,ys = np.meshgrid(points,points)
import matplotlib.pyplot as plt
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")
#利用数组进行逻辑运算
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])
print "如果cond里是True就输出xarr里的元素否则输出yarr里的:"
print [(x if c else y) for x,y,c in zip(xarr,yarr,cond)]
print "如果用np.where(cond,x,y)处理的话是相同的方法:"
print np.where(cond,xarr,yarr)

zarr = np.random.randn(4,4)
print zarr
print "如果元素大于0输出2,否则输出-2"
print np.where(zarr >0,2,-2)
print "如果元素大于0则输出2,否则保留原值"
print np.where(zarr>0,2,zarr)
#np.where的嵌套:np.where(cond1&cond2,0,np.where(cond1,1,np.where(cond2,2,3)))
#更复杂的形式是 result = 1*(cond1 -cond2)+2*(cond2& -cond1) +3*-(cond1|cond2) 虽然有点烧脑 但是还是可以看明白的
#这就提醒我们不能为了装逼把代码写的太短别人看起来烧脑
1
#数学统计学中的应用
2
arr3 = np.random.randn(5,4)
3
print "原随机数矩阵"
4
print arr3
5
print "所有元素的平均数:",arr3.mean()
6
print "每一列元素的均值,axis=0表示行:",arr3.mean(axis=1)
7
print "所有元素的和,同理括号里传入参数1表示每列所有元素的和,传入参数0表示每行所有元素的和:",arr3.sum()
8
print "所有行元素的累加,也就是第二行所有元素等于第一行加第二行的和:"
9
print arr3.cumsum(0)
10
print "所有列元素的累加"
11
print arr3.cumsum(1)
12
print "所行元素的累乘:"
13
print arr3.cumprod(0)
14
print "所有列元素的累乘:"
15
print arr3.cumprod(1)
16
print "计算标准差方差,同理可以传入参数来计算行或者列的标准差方差,可以通过传入ddof=来指定自由度,比如样本方差估计中的n-1"
17
print "标准差:",arr3.std(),"方差:",arr3.var()
18
print "样本方差",np.var(arr3,ddof=1)
19
print "np.argmax与np.argmin分别返回一个array中最大元素和最小元素的index,同理传入0位行1位列,以行为例,输出的array的维度等于列的维度,同时会标明是第几行。列同理。如果不拉成任何参数就是拉成一维的数数。"
20
print arr3.argmax()
21
print arr3.argmax(1)
22
print arr3.argmax(0)
23
print arr3.argmin()
24
print arr3.argmin(1)
25
print arr3.argmin(0)
26
print "一定记住1行0列啊!!重要的事情说三遍但我懒得打字三遍了"
#Bool数组的方法
arr4 = np.random.randn(100)
print "arr4里面大于0的数字的个数:",(arr4>0).sum()
bools = np.array([True,False,True,False])
print "Bools数组中是否有非零值:",bools.any()
print "Bools数组中是否全是非零值:",bools.all()
#any()和all()还可以用于非Bool数组,用来检测array里面是不是有0元素

#一维数组排序
arr5 = np.random.randn(5)
print arr5
arr5.sort()
print arr5
#多位数字按轴排序
print "如果sort()里面传入的参数为1,说明是按照大小顺序把每一行排列,如果里面传入的参数为0说明把每一列按照大小顺序排列"
print
arr6 = np.random.randn(4,4)
print "排序前:"
print arr6
arr6.sort(1)
print "按行排序后:"
print arr6
print
print "应用:计算一个array的分位数"
large_arr = np.random.randn(10000)
large_arr.sort()
print
print "计算一个1000个正态随机数的5%分位数,其中int函数表示取整"
print "large_arr[int(0.05*len(large_arr))]"
large_arr[int(0.05*len(large_arr))]

#还有一些其余的逻辑运算不再举例
#unique() 计算x中的唯一元素,返回一个有序的结果
#intersect1d(x,y) 计算xy中的公共元素,相当于取交集
#union(x,y) 计算xy的并集
#in1d(x,y) 表示在x的元素是否也在y中,返回Bool数组
#setdiff1d(x,y) 计算集合的差 相当于在x中且不在y中
#setxor1d(x,y) 集合的对称差 存在于其中某集合中但不同时存在于两个集合中
#Numpy文件的存取也是以array为基础
#函数分别是np.save('path',array_name) path是保存的路径,name是要储存的array的名字
#数组的读取用np.load("path")
#np.savez可以将多个数组保存到一个压缩文件里,加载时候会变成一个dict对象,对dict切片得到array
#Numpy在线性代数中的应用
2
x = np.array([[1,2,3],[4,5,6]])
3
y = np.array([[6,23],[-1,7],[8,9]])
4
print np.dot(x,y)#x.dot(y)
5
print
6
print np.dot(x,np.ones(3))
7
from numpy import linalg#用于线性代数的pack
8
X = np.random.randn(5,5)
9
print "X的内积:"
10
print X.T.dot(X)
11
print "x的内积的逆:"
12
print linalg.inv(X.T.dot(X))
13
print "矩阵的QR分解:"
14
q,r = linalg.qr(X.T.dot(X))
15
print "Q:"
16
print q
17
print "R:"
18
print r
19
#linalg里面还有很多很强大的线性代数的函数
20
#dot表示矩阵乘法,语法为x.dot(y)或者dot(x,y)这里的xy是要注意顺序的
21
#trace计算矩阵的迹 det为计算行列式
22
#eig表示计算矩阵的特征值和特征向量,这是个返回两个参数的函数,第一个是特征值第二个是特征向量,要注意这里的输入必须是方阵
23
#svd表示计算矩阵的奇异值分解
24
#solve表示求解Ax=b的线性方程组,其中A是一个方阵
25
#lstsq表示求解Ax=b的最小二乘解,用于超定方程
#Numpy的随机数生成

#生成一组4*4的标准正态分布的随机数
samples = np.random.normal(size=(4,4))
print samples

#np.random里面部分函数的说明
#seed生成随机数的种子
#shuffle对一个序列进行随机排序
#rand返回均匀分布的序列
#randint指定上下限选取整数
#randn标准正态分布
#binomial/normal/beta/chisquare/gamma/uniform分别表示各自的分布下选取随机数
#随机数的应用:生成随机游走的序列
2
nsteps = 1000
3
draws = np.random.randint(0,2,size = nsteps)
4
steps = np.where(draws>0,1,-1)
5
walks = steps.cumsum()
6
print walks.min()
7
print walks.max()
8
print (np.abs(walks) >= 10).argmax()#找出这个随机游走在10的时候的首达时
9
​
10
#一次模拟多个随机游走
11
nwalks = 5000
12
nsteps = 1000
13
draws = np.random.randint(0,2,size=(nwalks,nsteps))
14
steps = np.where(draws>0,1,-1)
15
walks = steps.cumsum(1)
16
print walks
17
#计算以上随机游走穿越30或者-30的最小时间,不是让这5000个都穿越,所以我们用any函数
18
hits30 = (np.abs(walks)>=30).any(1)
19
print "各个随机游走是否到达了距离原点30的位置:",hits30
20
print "5000个随机游走里一共有几个到达了30:",hits30.sum()
21
​
22
crossing_times = (np.abs(walks[hits30])>=30).argmax(1)
23
print crossing_times.mean()
24
​
25
#同时可以用其他的分布生成随机游走
26
#例如steps = np.random.normal(loc=0,scale=0.25,size = (nsteps,nwalks))

-11
22
27
[[  1   0   1 ..., -10 -11 -12]
[ -1   0  -1 ..., -40 -39 -40]
[  1   2   3 ...,  26  25  24]
...,
[ -1  -2  -1 ...,   4   5   6]
[  1   0   1 ..., -16 -17 -16]
[ -1  -2  -1 ...,  10  11  12]]
各个随机游走是否到达了距离原点30的位置: [False  True  True ..., False  True  True]
5000个随机游走里一共有几个到达了30: 3428
507.378646441
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息