数据分析之利刃之Numpy
什么是Numpy:
一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算
numpy创建数组
import numpy as np
t1 = np.arange(12)
t1
a = np.array([1,2,3,4,5])
a
b = np.array(range(1,6))
b
a.dtype
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
array([1, 2, 3, 4, 5])
array([1, 2, 3, 4, 5])
dtype('int64')
np.arange的用法:arange(start,stop,step),a,b,t1的数据类型都是int64
numpy中的数据类型
numpy中的数据类型如下:
数据类型的操作
指定创建的数据类型
a = np.array([1,0,1,0],dtype=np.bool)
a
array([ True, False, True, False])
修改数组的数据类型
a.astype(np.int8)
array([1, 0, 1, 0], dtype=int8)
保留小数点的位数
c = np.array([1.089532,2.43258492,3.47954902,.217950,5.532109594])
np.round(c,3)
array([1.09 , 2.433, 3.48 , 0.218, 5.532])
数组的形状
t1 = np.arange(12)
t1.shape
t1.reshape(3,4)
(12,)
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
像t1.reshape()这样有返回值,一般本身是不会变化的,也就是需要把t1.reshape(3,4)再赋值给t1才可以
如何将二维数组或更高维转换成一维呢?
t2 = np.arange(24).reshape(2,3,4)
t2
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
t2是三维矩阵,将它转化成一维
t2.flatten()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23])
数组计算
数组和数的加减乘除
t5 = t2.reshape(4,6)
t5
t5+2
t5*2
t5/2
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
array([[ 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25]])
array([[ 0, 2, 4, 6, 8, 10],
[12, 14, 16, 18, 20, 22],
[24, 26, 28, 30, 32, 34],
[36, 38, 40, 42, 44, 46]])
array([[ 0. , 0.5, 1. , 1.5, 2. , 2.5],
[ 3. , 3.5, 4. , 4.5, 5. , 5.5],
[ 6. , 6.5, 7. , 7.5, 8. , 8.5],
[ 9. , 9.5, 10. , 10.5, 11. , 11.5]])
这是由numpy的广播机制造成的,在运算过程中,加减乘除的值被广播到所有元素上面。
数组和数组的加减乘除
t6 = np.arange(100,124).reshape((4,6))
t6
array([[100, 101, 102, 103, 104, 105],
[106, 107, 108, 109, 110, 111],
[112, 113, 114, 115, 116, 117],
[118, 119, 120, 121, 122, 123]])
t6+t5
t6*t5
array([[100, 102, 104, 106, 108, 110],
[112, 114, 116, 118, 120, 122],
[124, 126, 128, 130, 132, 134],
[136, 138, 140, 142, 144, 146]])
array([[ 0, 101, 204, 309, 416, 525],
[ 636, 749, 864, 981, 1100, 1221],
[1344, 1469, 1596, 1725, 1856, 1989],
[2124, 2261, 2400, 2541, 2684, 2829]])
注意:数组的计算,是按照shape从后往前一一对应,如果后面的能对应上,则能够计算,例如shape(3,3,2)可以和shape(3,3,2)和shape(3,2)和shape(2,)进行计算
numpy中的轴
在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴
有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值
numpy读取和存储数据
np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
参数 | 解释 |
---|---|
frame | 文件,字符串或生成器,可以是压缩包 |
dtype | 数据类型,CSV的字符串以什么数据类型读入数组,默认np.float |
delimiter | 分隔字符串,默认是任何空格,改为逗号 |
skiprows | 跳过前x行,一般跳过表头 |
usecols | 读取指定的列,索引,元组类型 |
unpack | 如果为true,执行转置,读取属性将分别写入不同数组变量,False读取数据只写一个数组变量,默认为False |
numpy中的转置
t2 = np.arange(24).reshape((4,6))
t2.transpose()
array([[ 0, 6, 12, 18],
[ 1, 7, 13, 19],
[ 2, 8, 14, 20],
[ 3, 9, 15, 21],
[ 4, 10, 16, 22],
[ 5, 11, 17, 23]])
t2.T
t2.swapaxes(1,0)#轴交换
array([[ 0, 6, 12, 18],
[ 1, 7, 13, 19],
[ 2, 8, 14, 20],
[ 3, 9, 15, 21],
[ 4, 10, 16, 22],
[ 5, 11, 17, 23]])
numpy索引和切片
t2
t2[1]#取一行
t2[:,1]#取一列
t2[1:3]#取多行
t2[:,1:3]#取多列
t2[1:2:,1:3]#取行列交叉值
t2[[1,3],:]#取不相邻的行
t2[:,[2,4]]#取不相邻的列
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
array([ 6, 7, 8, 9, 10, 11])
array([ 1, 7, 13, 19])
array([[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
array([[ 1, 2],
[ 7, 8],
[13, 14],
[19, 20]])
array([[7, 8]])
array([[ 6, 7, 8, 9, 10, 11],
[18, 19, 20, 21, 22, 23]])
array([[ 2, 4],
[ 8, 10],
[14, 16],
[20, 22]])
numpy数值修改
只需要把通过索引取出来的值重新赋值就可以了。
t2[:,[2,4]]=0
t2
array([[ 0, 1, 0, 3, 0, 5],
[ 6, 7, 0, 9, 0, 11],
[12, 13, 0, 15, 0, 17],
[18, 19, 0, 21, 0, 23]])
也可以通过布尔索引来赋值
t2[t2<10]=0
t2
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
numpy的三元运算符进行修改
t2 = np.arange(24).reshape((4,6))
np.where(t2<10,0,10)
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 10, 10],
[10, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 10]])
表示把小于10的变为0,大于等于10的变成10
numpy的裁剪与拼接
裁剪:
t2 = np.arange(24).reshape((4,6))
t2.clip(10,15)#表示把小于10的变为10,大于15的变为15
array([[10, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 11],
[12, 13, 14, 15, 15, 15],
[15, 15, 15, 15, 15, 15]])
行交换与列交换
t2[[0,1],:] = t2[[1,0],:]#行交换
array([[ 6, 7, 8, 9, 10, 11],
[ 0, 1, 2, 3, 4, 5],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
t2[:,[0,1]] = t2[:,[1,0]]#列交换
array([[ 1, 0, 2, 3, 4, 5],
[ 7, 6, 8, 9, 10, 11],
[13, 12, 14, 15, 16, 17],
[19, 18, 20, 21, 22, 23]])
拼接
a1 = np.arange(12).reshape((2,6))
np.vstack((a1,a1))#竖直拼接
np.hstack((a1,a1))#水平拼接
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
array([[ 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11, 6, 7, 8, 9, 10, 11]])
numpy统计函数
numpy中的常用统计函数
用途 | 函数名 |
---|---|
求和 | t.sum(axis=None) |
均值 | t.mean(a,axis=None) 受离群点的影响较大 |
中值 | np.median(t,axis=None) |
最大值 | t.max(axis=None) |
最小值 | t.min(axis=None) |
极值 | np.ptp(t,axis=None) 即最大值和最小值只差 |
标准差 | t.std(axis=None) |
def fill_ndarray(t1):
for i in range(t1.shape[1]):#t1.shape[1]是列数
temp_col = t1[:,i]#当前的一列
nan_num = np.count_nonzero(temp_col!=temp_col)
if nan_num !=0:#证明这一列有nan
temp_not_nan_col = temp_col[temp_col==temp_col]#当前列不为nan的值
#选中当前为nan的位置,值为不为nan的均值
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()
return t1
if __name__ == '__main__':
t1 = np.arange(12).reshape(3,4).astype("float")
t1[1,2:] = np.nan
t1 = fill_ndarray(t1)
print(t1)
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
上面代码是将矩阵中的nan替换成当前列的均值。
numpy更多用法
获取最大值最小值的位置
np.argmax(t,axis=0)
np.argmin(t,axis=1)
创建一个全0的数组: np.zeros((3,4))
创建一个全1的数组:np.ones((3,4))
创建一个对角线为1的正方形数组(方阵):np.eye(3)