主要基于《利用python进行数据分析:第4章》以及Numpy官网的tutorial。
Numpy是numerical python的简称,是高性能科学计算和数据分析的基础包。
Numpy最主要的对象是homogeneous multidimensional array(齐次多维数组),是同样类型的elements组成的table。In NumPy dimensions are called axes(轴)。
Numpy的数组对象叫ndarray
,是一个快速而灵活的大数据集容器。它是一个通用的同构数据多维容器,其中所有元素必须是相同类型的。numpy.array 和python标准库当中的array.array是不同的,后者只有一个维度。
可以利用这种数组对整块数据执行一些数学运算,语法跟标亮元素之间的运算一样。
每个数组都有一个ndarray.shape
(一个表示各维度大小的元组tuple)和一个ndarray.dtype
(一个说明数组数据类型的对象)。ndarray.ndim
表示维度的大小,ndarray.size
表示数组当中elements的总数,ndarray.itemsize
指每个element的bytes大小,ndarray.data
表示含有实际elements的缓冲区。
>>>data.dtype
dtype('int64')
创建数组最简单的方法是array函数。它接受一切序列型的对象(可以是python的tuple或者list),然后产生一个新的NumPy数组。
除非显式说明,np.array会尝试为新建的这个数组推断出一个较为合适的数据类型(保存在dtype对象中)。
嵌套数据将会被转化为多维数组。
zeros
,ones
可以创建指定长度或形状的全0或全1数组。
>>>np.zeros((3,6))
用这些方法创建多维数组,需要传入一个表示形状的元组。
arange
是python内置函数range的数组版。
>>>np.arange(15)
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
如果没有特别指定,数据类型基本都是float64。
数组创建函数表格:
函数 | 说明 |
---|---|
array | 将输入数据转化为ndarray,默认直接复制 |
asarray | 将输入转化为asarray,如果本身是ndarray就不复制 |
arrange | 类似于range,返回一个全array |
ones, ones_like | 创建全1数组,后者是以另一个数组的形状和type创建全1数组 |
zeros, zeros_like | 创建全0数组 |
empty, empty_like | 创建新数组,只分配内存空间不填充任何值 |
eye, identity | 创建1个正方的NxN单位矩阵 |
Array和asarray有什么区别?主要区别就是当数据源是ndarray时,array仍然会copy出一个副本,占用新的内存,但asarray不会。
举例:
arr1=np.ones((3,3))
arr2=np.array(arr1)
arr3=np.asarray(arr1)
arr1[1]=2
print 'arr1:\n',arr1
print 'arr2:\n',arr2
print 'arr3:\n',arr3
输出:
arr1:
[[ 1. 1. 1.]
[ 2. 2. 2.]
[ 1. 1. 1.]]
arr2:
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
arr3:
[[ 1. 1. 1.]
[ 2. 2. 2.]
[ 1. 1. 1.]]
dtype含有ndarray将一块内存解释为特定数据类型所需的信息。
数值型dtype的命名方式相同:一个类型名+表示各元素位长的数字。
标准的双精度浮点值(Python中的float对象)需要占用8字节(64位),因此该类型在NumPy中记作float64。
位:“位(bit)”是电子计算机中最小的数据单位。每一位的状态只能是0或1。
字节:8个二进制位构成1个“字节(Byte)”,它是存储空间的基本计量单位。1个字节可以储存1个英文字母或者半个汉字,换句话说:1个汉字占据2个字节的存储空间。
字:计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(word)。“字”由若干个字节构成,字的位数叫做字长,不同档次的机器有不同的字长。例如一台8位机,它的1个字就等于1个字节,字长为8位。如果是一台16位机,那么,它的1个字就由2个字节构成,字长为16位。字是计算机进行数据处理和运算的单位。
KB:K表示1024,也就是2的10次方。1KB表示1K个Byte,也就是1024个字节。
可以通过numpy的astype
方法显式地转换其type。
调用astype
会创建出一个新的数组(原始数据的一份拷贝),即使新type和老type相同也是如此。
大小相等的数组之间的任何算术运算都会将运算应用到元素级,不用编写循环。
同样,标量与数组的算数运算也会将那个标量值传播到各个元素。
不同大小的数组之间的运算叫做广播(broadcastig)。
跟列表的区别在于,数组的切片是原始数组的视图,即数据不会被复制。
视图上的任何修改都会被反映到数据源上。
>>> arr=np.arange(10)
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> arr_slice=arr[5:8]
>>> arr_slice
array([5, 6, 7])
>>> arr_slice[:]=90
>>> arr_slice
array([90, 90, 90])
>>> arr
array([ 0, 1, 2, 3, 4, 90, 90, 90, 8, 9])
如果想要得到切片的一份副本,需要显式地进行操作,如arr[5:8].copy()
对于多维数组,可以对各个元素进行递归访问,也可以传入一个以逗号隔开的索引列表选取单个元素。
布尔型数组可以用于数组索引,布尔型数组的长度必须跟被索引的轴长度一致。
此时会创建数据的副本。
Python关键字and或or在布尔型数组中无效。
利用整数数组选取子集。
以特定顺序选取子集。
跟切片不一样,将数据复制到新数组中。
相当于矩阵的转置。
比如np.dot(arr, arr.T)
可以计算矩阵内积。
对于高维数组,有transpose, swapaxes
方法。
是一种对ndarray中的数据执行元素级运算的函数。可以将其看作简单函数的矢量化包装器。
比如np.maximum
,np.sqrt
等。
meshgrid函数:
numpy提供的numpy.meshgrid()函数可以让我们快速生成坐标矩阵X,Y。
语法:X,Y = np.meshgrid(x, y)
输入的x,y,就是网格点的横纵坐标列向量(非矩阵) 。
输出的X,Y,就是坐标矩阵。
where函数:
numpy的where函数是x if condition else y 的矢量化版本。
可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算。如sum
,mean
,std
函数等。
mean和sum能接受一个axis参数,用于计算该轴向上的统计值。
关于axis:
>>> data = np.array([
... [1,2,1],
... [0,3,1],
... [2,1,4],
... [1,3,1]])
>>> np.sum(data, axis=1)
array([4, 4, 7, 5])
>>> np.min(data, axis=0)
array([0, 1, 1])
即通过不同的axis,numpy会沿着不同的方向进行操作:如果不设置,那么对所有的元素操作;如果axis=0,则沿着纵轴进行操作;axis=1,则沿着横轴进行操作。但这只是简单的二位数组,如果是多维的呢?可以总结为一句话:设axis=i,则numpy沿着第i个下标变化的方向进行操作。
在numpy中,使用的axis的地方非常多,处理上文已经提到的average、max、min、sum,比较常见的还有sort(排序)和prod(乘积)。