×
广告

python数据分析基础:numpy

96
单线程程序员
2018.09.30 19:55* 字数 1403

numpy是python高性能科学计算和数据分析的基础包,python的很多其他库都构建在numpy之上,因此你要用python做数据分析与挖掘都最好先学一下numpy的基本操作(当然要学numpy首先要把python语言本身的基本操作要学一下),这也是我看吴恩达神经网络基础课程的感受,否则听的时候可能听懂了,但是写代码的时候,发现下不了手,甚至就算看着别人的代码来写,也总感觉很模糊。

python语言提供了list容器,而ndarray是numpy提供的多维数组对象,拥有一系列好用的属性和方法,因为我装的是anaconda,numpy等常用科学计算包都是是默认安装的,所以可以直接引入numpy包

import numpy as np

创建ndarray

通过numpy提供的array函数np.array(data,dtype=np.int32)可以创建ndarray,同时可以指定元素数据类型,如不指定,numpy会自己推断较合适的数据类型,对于大数据集,一定要关注自己的数据类型,如图像的像素值都是0-255之间的数,因此用无符号的8位就够了,但如果用4个字节的int,每个像素点就会浪费3个字节,一张64*64的图片就会浪费12288个字节,即12kb,这对于大数据集是非常可怕的。具体有哪些数据类型这里不作介绍,需要的时候去查就好了。

# 一维
data = [1, 2, 3, 4, 5];
arr = np.array(data)
# 二维
data = [
    [1, 2, 3, 4],
    [4, 5, 6, 7]
]
arr = np.array(data)
# 三维 以64*64*3图片为例,64*64表示长宽,3表示每个像素的rgb值
data = [
     // 一列或一行
     [
          [120, 255, 0], //每一列或每一行的每个像素点
          [110, 123, 1],
          ... # 共64个
     ],
     [
          [130, 205, 0],
          [160, 123, 1]
     ],
     ... # 共64个
]
# n维同理

除此之外,numpy也提供了一些方法来创建一些经常用到的数组。

# 创建10个元素全为0的数组
np.zeros(10)
# 创建3*6的全为0的数组
np.zeros((3,6))
# 创建10个元素全为1的数组
np.ones(10)
# 创建2*3的随机数组
arr = np.random.random((2,3))
# 创建从0-14的整数数组
np.arange(15)
# 创建一个10*10单位矩阵,即左上到右下的对角线元素为1,其余全为0
np.eye(10)

ndarray常用属性

以上文中提到到图片三维ndarray为例

# ndaray的维度
print(arr.ndim)  # 因为是三维 所以是3
# ndarray的形状
print(arr.shape) # (64,64,3)
print(arr.shappe[0]) # 64
# ndarray所有元素的个数
print(arr.size) # 64*64*3 = 12288
# ndarray的数据类型
print(arr.dtype) # int32

ndarray索引和切片

数组索引即如何找到数组中的元素,ndarray数组索引除了支持标量,同时还支持切片,以及花式索引(这里不作介绍)。再说切片之前,先说"轴",一个ndarray至少有一个轴,一维只有一个x轴,二维的话有x轴和y轴,三维再加一个z轴,多维同理。有n个维度,则最多支持n个索引。如三维数组,可以通过arr[a]、arr[a][b]或者arr[a,b]、arr[a][b][c]或者[a,b,c]取到某个特定的元素。
a,b,c除了可以为具体的数字,也可以为一个切片。和python中的list一样,通过冒号:表示切片,只有:表示整个轴。:前后都可以写数字,如1:5,表示这个轴上从1到5的元素,1:则表示这个轴上从1到最后一个元素:6则表示这个轴上从0到第6个元素,元素可能是一个标量也可能是一个子数组,示例如下:

arr = np.arange(10)
print(arr) # [0,1,2,3,4,5,6,7,8,9]
print(arr[3]) # 3
print(arr[:]) # 一维只有一个x轴,因此输出 [0,1,2,3,4,5,6,7,8,9]
print(arr[3:5]) # x轴上3-5的元素 输出 [3,4]
# 二维数组
arr = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print(arr[0]) # [1,2,3,4]
print(arr[:]) 
print(arr[:,:])
# 上面这俩条都会返回整个array
print(arr[1,2:]) # 第一维度上的第一个元素,从第0个开始到最后一个元素 即 [7,8]
print(arr[:2]) # 第一个维度从0到第2个元素 即 [ [1,2,3,4], [5,6,7,8] ]
print(arr[:2,:1]) # [[1],[5]]

需要注意的是,ndarray中的切片都是原数组的视图,因此对切片的任何操作都会体现到原数组中,如果需要拷贝数组,需要显示的调用copy函数。示例如下

arr = np.arange(10)
print(arr) # [0,1,2,3,4,5,6,7,8,9]
print(arr[3:5]) # [3,4]
arr[3:5] = 12 # 修改切片同时会修改原数组
print(arr[3:5]) # [12,12]
print(arr) # [0,1,2,12,12,5,6,7,8,9]
copy = arr.copy()
copy[3:5] = 8
print(copy) # [0,1,2,8,8,5,6,7,8,9]
print(arr) # [0,1,2,12,12,5,6,7,8,9]

ndarray运算

大小相等的数组的数组之间的任何运算都会应用到元素级别。例如:

arr1 = np.array([[1,2,3],[4,5,6]])
arr2 = np.array([[1,2,3],[4,5,6]])
print(arr1*2) # [[2,4,6],[8,10,12]]
print(arr1+arr2) # [[2,4,6],[8,10,12]]
print(arr1*arr2) # [[1,4,9],[16,25,36]]

ndarray常用函数

有些是在numpy命名空间下的,有些则是要通过具体的数组对象来调用,,有的则都可以。下文中,np.func()表示在numpy命名空间下,arr.func()则表示通过具体数组对象调用。
数组重塑 arr.reshape(newshape) 参数为一个表示新数组形状的元组。作为参数形状的其中一维可以是-1,表示该维度大小由数据本身推断而来。示例如下:

arr = np.arange(15).reshape(3,5)
print(arr)
# [
#      [0,1,2,3,4],
#      [5,6,7,8,9],
#      [10,11,12,13,14]
# ]
arr = np.arange(15).reshape(3,-1)
# 输出和上面的一样

数组转置arr.transpose() 无参数,也可以直接用T属性表示,如arr.T表示arr的转置。如果你还记得线性代数,那么转置矩阵听起来一定很耳熟二维数组转置比较好理解,即行变成列,列变成行。三维及其以上稍微复杂点,这里不介绍。
矩阵点乘 np.dot(x,y) 或者 arr.dot(arr.T) 这也是专门针对线性代数提供的函数,关于点乘,等同于线性代数里的矩阵乘法,因此要满足前一个矩阵A的列数等于后一个矩阵B的行数,矩阵乘法才有意义
除了dot函数,还有其他针对线性代数的函数,但这个在后面的代码中会经常用到。
arr.sort()排序函数
常用的数学计算以及分析统计函数
这个有很多,最常见的如求和,求平均值,求方差,标准差,指数,对数等。需要做统计和计算的时候,先查下API文档,看有没有官方提供的函数。能用numpy函数的就用函数,尽量不要自己写循环处理数组,numpy数组的性能是非常好的。
以上并不是numpy数组的全部知识,只是我看了吴恩达神经网络基础课程认为当下上手编写代码需要具备的知识。

主要参考资料:利用python进行数据分析

神经网络
Web note ad 1