Python数据分析特训课笔记
python数据分析班 笔记NUMPY用法
1.numpy的构建
除了.ones和eye用法还有其他的用法
#Using full
np_full = np.full((3,3),10)
#Or using empty
np_unitialised = np.empty((3,3))
#Or using arange
np_from_zero_to_specified = np.arange(15)
numpy的随机矩阵的几种构建方式
除了说到的常用的np.random.random((x,y))还有其他几种:
#Method1
np.random.normal(0,1,(3,3))
#Method2
np.random.seed(0)
np.random.randint(0,10, 6)
#Method3
rng = np.random.RandomState(255)
x = rng.randint(1,10,(3,4))
y = rng.uniform(1,10,(3,4))
z = rng.randn(100)
使用这个seed和RandomState的目的都是为了测试的时候随机出来的每次都是一样的,这样方便调试。
数组的类型可以进行自己定义
使用的keyword argument是dtype
int_arr = np.array(range(1,5),dtype = np.int32)
print(int_arr, int_arr.dtype) #[1 2 3 4] int32
float_arr = int_arr.astype(np.float32)
print(float_arr,float_arr.dtype)# [1. 2. 3. 4.] float32
只要是可以转成数字的string也是可以转型的:
str_arr = np.array(['11','22','33'],dtype=np.string_)
print(str_arr) #[b'11' b'22' b'33']
float_arr = str_arr.astype(np.float64)
print(float_arr) # [11. 22. 33.]
2. Numpy的切片
注意下维度的变化,第二个例子中由于是对row取了切片的操作,所以这个出来的维度需要增加一维(比如如果是1:3,就必须是得增一维)
test = my_grid[1,:]
print(test, test.shape)#[4 5 6 7] (4,)
test2 = my_grid[1:2, :]
print(test2, test2.shape) # [[4 5 6 7]] (1, 4)
test3 = my_grid[[1], :]
print(test3, test3.shape)# [[4 5 6 7]] (1, 4)
3. Fancy Indexing
注意一下, 数组里面的index的维度是一维的,这个index维度决定最后的维度:
print(a[[0,1],[0,2]]) #[1 4 5]
print(a[[0,1],[0,2]].shape) # (3,)
# 假如x = array([ 1, 33, 49, 17, 48, 94, 79, 72, 93, 11])
ind2 = np.array([[3,4],
[1,2]])
print(x[ind2]) # index influences the shape, NOT x! #array([[17, 48],[33, 49]])
4. Masking
这个的使用其实有比讲的更灵活的方式
假如一年的降水量是个array :
inches = np.array([245., 14., 13., 17., 8., 6., 5., 6., 4., 3., 7.,
6., 3., 3., 3., 4., 4., 2., 4., 0., 0., 1.,
1., 1., 0., 0., 0., 2., 1., 1., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 1.])
那我怎么求降水量大于1小于4的天数值呢?
首先可以大于1是一个条件:
(inches >1)
首先可以小于4也是一个条件:
(inches <4)
满足两个值的boolean expression (也就是一个array, 里面要不就是true要不就false) 就是
(inches >1)&(inches <4)
#天数值就是:
np.sum((inches >1)&(inches <4))
如果要求降水量大于1小于4的降水量median值
np.median(inches[(inches >1)&(inches <4)])
再比如,利用mask去取一些特定行或者列的值:
print(my_grid)
my_row_mask = np.array([1,0,0,1],dtype=np.bool)
print(my_row_mask)
print(my_grid[my_row_mask,2])
输出:
[[ 0 999 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 12 13 14 15]]
[ True False False True]
[ 2 14]
masking和fancy index是一个很强的组合,一定要掌握。
5. 数学运算
arr = np.arange(16).reshape(2,2,4)
输出:
[[[ 0 1 2 3]
[ 4 5 6 7]]
[[ 8 9 10 11]
[12 13 14 15]]]
最外层的[]是0-axis, 中间层是1-axis, 里面是2-axis (记住这个原则就不会有问题!), 所以这个高维矩阵元素可以在0,1,2axis的坐标体系下表示为:
新坐标下的tensor的表示方法
本来的结构是(0,1,2)也就是最外层的[]是0-axis, 中间[]是1-axis, 里面是2-axis,使用transpose进行变化,将0,1这两个轴进行交换,会发生什么呢?
print(arr.transpose((1,0,2)))
输出
[[[ 0 1 2 3]
[ 8 9 10 11]]
[[ 4 5 6 7]
[12 13 14 15]]]
为什么用transpose之后会输出这个值呢?其实把0,1轴进行交换后,参看上面的图,你就发现4,5,6,7这几个数字就到了0轴上面的索引为1的位置,8,9,10,11这个几个数字就到了1轴上面索引为1的位置,从几何意义反馈到空间矩阵意义的变化就是,0轴表示最外层,索引为1表示第二个,即4,5,6,7在最外层的[]的第二个元素。 同样可以得到8,9,10,11,在中间括号的[]里面的第二个位置,所以本质上就是把第二排和第三排交换了位置。
假如是1,2轴的位置互换呢?
print(arr.transpose((0,2,1)))
输出的结果猜想一下,0轴没有变,说明最外头的括号里面的元素还是没有变,应该还是两坨,一坨是0-7,另一坨8-15。
那么0-7的位置发生了什么变化呢,就是坐标轴互换了,原来的排列是0,1,2,3一排,4,5,6,7一排,两排成行,现在是0,1,2,3是成列,4,5,6,7成列,两列成列。也就是:
[[[ 0 4]
[ 1 5]
[ 2 6]
[ 3 7]]
[[ 8 12]
[ 9 13]
[10 14]
[11 15]]]
注意1,2轴互换除了可以用transpose做到,还可以使用另外一个函数:
arr.swapaxes(1,2)
关于numpy.sum的里面的轴的关系很好记,如果是axis=0就表示沿着0轴的方向进行求和运算,也就是相当于把第0维去掉了。
6. Numpy的reshape
这一部分的东西主要是靠几个最主要的函数, 把这几个几号就行了
arr = np.arange(4).reshape((2,2)). ravel()
np.concatenate((x,y),axis = 0) # 纵向的叠加
l = np.concatenate((x,y),axis = None) # 全部拉伸
np.vsplit(arr,2)
np.hsplit(arr,2)
np.vstack(x,y) # 等价于np.r_[x,y] 表示添加row的stack
np.hstack(x,y) # 等价于np.c_[x,y]
arr = np.arange(3) # repeat
print(arr.repeat(3))
print(arr.repeat([2,3,4]))