python Numpy
Numpy → Pandas → 掌握一些数据清洗、规整、合并等功能 → 掌握类似与SQL的聚合等数据管理功能 → 能够用Python进行统计建模、假设检验等分析技能 → 能用Python打印出100元钱 → 能用Python帮我洗衣服、做饭 → 能用Python给我生小猴子......
定下了这个目标,就从Numpy开始把!
第三天我的学习大纲:
一、数据格式
二、数组运算
-
加、减、乘、除、内积、转置
-
索引和分片
-
数组拆分
三、通用函数
-
数学运算
-
统计方法
-
一些逻辑方法
-
随机数生成
-
存储与导入
经过这些学习大纲,对Numpy有一个比较扎实的了解。
一、数据格式
Numpy提供了一种多维的数组对象ndarray,先认识一下:
>>> data1=[1,2,3]
>>> data1
[1, 2, 3]
>>> a=np.array(data1)
>>> a
array([1, 2, 3])
>>> data2=[[1,2,3],[4,5,6]]
>>> data2
[[1, 2, 3], [4, 5, 6]]
>>> b=np.array(data2)
>>> b
array([[1, 2, 3],
[4, 5, 6]])
a是一维数组,b是多维数组。我们再认识一下它的数据类型:
>>> a.dtype
dtype('int32')
>>> b.dtype
dtype('int32')
如果是字符串呢?看一下:
>>> c=np.array(['shu','shuo','jun'])
>>> c.dtype
dtype('S4')
Numpy提供这样的数组非常的方便灵活,有多方便灵活呢?看下面的日记内容。
二、数组运算
1. 加、减、乘、除、内积、转置
运算起来就发现ndarray的灵活方便了,比如一个数组a:
>>> a=[[1,2,3],[4,5,6]]
>>> a+a
[[1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6]]
>>> a*a
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
a*a
TypeError: can't multiply sequence by non-int of type 'list'
a+a其实是两个列表合并,而两个列表是不可以相乘的,至于减和除则都不可以了。
但是,ndarray可以:
>>> npa = np.array(a)
>>> npa+npa
array([[ 2, 4, 6],
[ 8, 10, 12]])
>>> npa-npa
array([[0, 0, 0],
[0, 0, 0]])
>>> npa*npa
array([[ 1, 4, 9],
[16, 25, 36]])
>>> npa/npa
array([[1, 1, 1],
[1, 1, 1]])
可以直接实现矩阵元素的加减乘除,注意,这个运算是元素级别的运算!
那么两个矩阵的相乘要怎么算呢?其实就是内积啦:
>>> b=np.dot(npa,npa.T)
>>> b
array([[14, 32],
[32, 77]])
用np.dot(X,Y)就可以计算两个矩阵X和Y的内积,顺便再介绍一下,.T就是求转置,npa.T就是矩阵npa的转置。
2. 索引和分片
在【统计师的Python日记】第一天的日记中,就已经学习了数组的分片,
>>> c='hello'
>>> c[0:3]
'hel'
>>> c[0:4:2]
'hl'
在Numpy的数组中也有这样的操作:
>>> c=np.array([1,2,3,4,5,6])
>>> c[2:4]
array([3, 4])
但是,这样隐藏了一个numpy数组的巨大不同,注意看下面的结果!
>>> c=np.array([1,2,3,4,5,6])
>>> cs=c[2:4]
>>> cs
array([3, 4])
>>> cs[1]=999
>>> cs
array([ 3, 999])
>>> c
array([ 1, 2, 3, 999, 5, 6])
注意看,我对cs进行操作,将array([3, 4])的4变成了999,结果c中的4也变成了999!
因为,在numpy中,cs是c的一个视图,而不是副本!这是因为numpy处理的是大数据,它会尽可能的避免数据复制来复制去,以保证性能的节省。
是不是很高冷?!
所以在numpy操作中要很小心,如果非要生成一个副本,则可以用.copy()操作:
cs=c[2:4].copy()
此时的cs就和c一点没关系了,可以放心的操作。
3. 数组拆分
用.reshape((a,b))可以将数组拆分成a×b的数组:
>>> x=np.array([1,2,3,4,5,6,7,8,9,10,11,12])
>>> x.reshape((3,4))
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
三、通用函数
学习完Numpy数组的基本格式、基本的运算,再学习一下高级一些的通用函数,书上这么写道:
“通用函数(ufunc)是一种对ndarray中的数据执行元素级运算的函数”
1. 数学运算
主要是进行一些数学的运算,如求开方、求e的n次幂、平方等等。
-
sqrt() 求开方
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> np.sqrt(a)
array([[ 1. , 1.41421356, 1.73205081],
[ 2. , 2.23606798, 2.44948974],
[ 2.64575131, 2.82842712, 3. ]])
-
exp()求e次幂
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> np.exp(a)
array([[ 2.71828183e+00, 7.38905610e+00, 2.00855369e+01],
[ 5.45981500e+01, 1.48413159e+02, 4.03428793e+02],
[ 1.09663316e+03, 2.98095799e+03, 8.10308393e+03]])
其他方法如下表:
函数 |
说明 |
abs |
绝对值 |
square |
平方根 |
log、log10、log2… |
自然对数、底数为10的log、底数为2的log… |
sign |
计算各元素的正负号 |
ceil |
计算大于等于各元素的最大整数 |
floor |
计算小于等于各元素的最大整数 |
rint |
四舍五入到最接近的整数 |
modf |
将数组的小数和整数部分以两个独立数组的形式返回 |
isnan |
查看各元素是否是NaN |
cos、cosh、sin、sinh、tan、tanh |
三角函数 |
add(a,b) |
a+b |
subtract(a,b) |
a/b |
multiply(a,b) |
a*b |
…… |
等等,有需要再具体查百度。
2. 统计方法
作为一名统计师,这个是我最喜欢的,Numpy提供了哪些常用的统计方法呢?
-
sort()排序
sort(a,0)是对竖轴上的元素进行排序;sort(a,1)是对横轴上的元素进行排序.
>>> a=np.array([[10,2,3],[4,15,6],[9,8,7]])
>>> a
array([[10, 2, 3],
[ 4, 15, 6],
[ 9, 8, 7]])
>>> np.sort(a,0)
array([[ 4, 2, 3],
[ 9, 8, 6],
[10, 15, 7]])
>>> np.sort(a,1)
array([[ 2, 3, 10],
[ 4, 6, 15],
[ 7, 8, 9]])
注意,Numpy的这个sort方法,返回的是数组a的副本,a数组本身不变!
-
sum()、mean()、std()
可以利用这些函数对数组求和、均值以及标准差:
>>> a
array([[10, 2, 3],
[ 4, 15, 6],
[ 9, 8, 7]])
>>> np.mean(a)
7.1111111111111107
>>> np.sum(a)
64
>>> np.std(a)
3.7843080813169783
也可以对行或者列进行统计计算,同样指定0和1即可:
>>> np.mean(a,1)
array([ 5. , 8.33333333, 8. ])
其他方法还有min、max、argmin、argmax等,需要时百度即可。
3. 一些逻辑方法
-
any()和all()
适用于布尔型数据,all()需要当元素全为True时,才返回True;any()需要任意元素为True,就返回True:
>>> a=np.array([True, True, False])
>>> a.any()
True
>>> a.all()
False
-
in1d(a,b)查找成员资格
用来测试一个数组a在另一个数组b中的成员资格,返回布尔值
>>> a
array([ 1, -1, 2])
>>> b
array([ 4, 23, -9, 1, 3, 2])
>>> np.in1d(a,b)
array([ True, False, True], dtype=bool)
-
unique()
查找数组中的唯一值,返回已排序的结果
>>> a=np.array([1,3,3,4,5,6,7,5,5,6])
>>> np.unique(a)
array([1, 3, 4, 5, 6, 7])
4. 随机数生成
-
random.randn(m,n)
生成一个m×n的标准正态分布
>>> a=np.random.randn(3,4)
>>> a
array([[ 0.32363846, 1.22595324, -1.04776719, -1.14483233],
[ 3.07756974, -0.09599722, 0.4276572 , 0.76864267],
[ 0.18575346, -1.06510241, -0.91460616, -1.25091496]])
-
random.normal(mean, std, size=(m,n))
生成一个m×n矩阵,服从均值mean,标准差std的正态分布
>>> a=np.random.normal(2,1,size=(3,4))
>>> a
array([[ 0.13642552, 1.0807106 , 1.71524621, 2.2809086 ],
[ 1.6757182 , 1.47675827, 2.93552336, 1.16315545],
[ 2.36641683, 2.10758811, 3.40073296, 1.51738042]])
其他
Numpy.random.函数 |
说明 |
seed |
确定随机数生成器的种子 |
permutation |
返回一个序列随机排列 |
rand |
产生均匀分布的样本 |
randint |
从给定的上下限范围内随机选取整数 |
binomial |
产生二项分布的样本 |
beta |
产生beta分布的样本 |
chisquare |
产生卡方分布的样本 |
gamma |
产生伽马的样本 |
uniform |
产生(0,1)均匀分布的样本 |
等等,需要的时候再百度之。
5. 存储与导入
-
数组的储存与读取
不是储存一个数据,而是只储存一个numpy的数组!save这个函数可以做到。
save(‘d:/save_a’, a)
将数组a储存在d盘下,命名为save_a,会自动加上扩展名.npy
load(‘d:/save_a’)
读取相应的路径即可。
savez()
将多个数组保存到一个压缩文件中,比如将arr1和arr2两个数组都存起来,存在zip_array里。
-
数据的导入导出
使用loadtxt将数据导入,格式为:
np.loadtxt(‘路径’, delimiter=’分隔符’)
比如导入d盘下面的这个testSet.txt文件:
>>> a=np.loadtxt('D:/testSet.txt')
>>> a
array([[ -1.76120000e-02, 1.40530640e+01, 0.00000000e+00],
[ -1.39563400e+00, 4.66254100e+00, 1.00000000e+00],
[ -7.52157000e-01, 6.53862000e+00, 0.00000000e+00],
[ -1.32237100e+00, 7.15285300e+00, 0.00000000e+00],
[ 4.23363000e-01, 1.10546770e+01, 0.00000000e+00],
[ 4.06704000e-01, 7.06733500e+00, 1.00000000e+00],
[ 6.67394000e-01, 1.27414520e+01, 0.00000000e+00],
......
[ 1.38861000e+00, 9.34199700e+00, 0.00000000e+00],
[ 3.17029000e-01, 1.47390250e+01, 0.00000000e+00]])
注意反斜杠/的方向!
假如原数据是逗号分隔的,只要加上delimiter就好了:
np.loadtxt('D:/testSet.txt', delimiter=',')
这是导入,那么将数据导出呢?用savetxt()即可,将数据导出到以某种分隔符隔开的文本文件中。
今天学习了Numpy,明天开始学习Python的数据分析利器——Pandas!想继续偷窥我日记的朋友们可以关注数说工作室的微信哦~