Numpy的核心特征之一就是ndarray
一个ndarray是一个通用的多维同类数据容器,也即每一个元素均为相同类型。每一个数组都有一个shape属性,用来表征数组每一纬度的数量。每一个数组都有一个dtype属性,用来描述数组的数据类型
1 | data.shape ==> (2,3) |
生成 ndarrays
生成数组最简单的方式就是使用array函数。array可以接收任何序列型对象(也包括其他数组),生成一个新的包含传递数据的Numpy数组
1 | data = [[1,2,3,4],[5,6,7,8]] |
我们可以通过ndim和shape属性来验证
1 | arr.ndim ==> 2 |
np.array 会自动推断生成数组的数据类型,数据类型被保存在特殊的元数据dtype中
ndarray的数据类型
dtype是一个特殊的对象,它包含了ndarray需要为某一种类型数据所声明的内存信息(即数据的数据)。
1 | arr = np.array([1,2,3], dtype=np.floart(64)) |
可用astype方法显式地转换数组的数据类型(可用于将含数字字符串变为数字)
1 | arr = np.array([1,2,3,4,5]) |
np.float处也可以替换为其他数组的dtype类型
注意:astype时总是生成一个新的数组
numpy数组算术
numpy允许进行批量化操作而无需任何for循环,称这种特性为向量化
1 | arr = np.array([[1. ,2. ,3.],[4. ,5. ,6.]]) |
带有标量计算的算术操作会把值传递给每一个元素
1 | arr = np.array([[1. ,2. ,3.],[4. ,5. ,6.]]) |
同理同尺寸数组之间比较会产生一个布尔值数组。而不同尺寸的比较需要用到广播特性,将会在其他文章中的讲到。
基础索引与切片
数组可以像列表那样进行切片,但区别于python内建链表的是数组的切片是原数组的视图这意味着数组不会被复制,任何对于视图的修改都会反映到原数组上
1 | arr = np.arange(10) |
如果只是想要一份数组切片的拷贝的话就必须使用arr[5:8]显式地复制这个数组
对于多维数组,切片意味着切下低一维的元素
1 | arr = np.array([[1,2,3], |
如果将索引和切片混合使用则可以得到低纬度的元素
1 | arr = np.array([[1,2,3], |
注意:单独一个冒号表示整个轴上的数组,对切片表达式赋值的时候,整个切片都会重新赋值。
布尔索引
布尔索引将广泛用于数据处理中,例如我们有:
1 | names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) |
如果说每一个姓名对应于一行数据,那么当我们在筛选的时候使用
1 | print(names=='Bob') |
这里就生成了一个布尔索引数组,用于指明匹配情况,于是就可以用到我们的数组上面去了
1 | print(data[names=='Bob']) |
这里就把和数据集中和Bob对应的数据筛选出来了
如果要反选可以使用~,比如:
1 | cond = names =='Bob' |
注意:1、使用布尔值索引选择数据时,总是生成数据的拷贝 2、python关键字and和or无效,应使用& 和 |
神奇索引
神奇索引是numpy中的术语,用于描述使用整数数组进行数据索引
1 | arr = np.empty((8,4)) |
这里的4,3,5,6就是指定在arr中的行数,如果索引为负则会从尾部选择
注意:神奇索引与切片不同,它总是将数据复制到一个新的数组中
数组的转置和换轴
转置是一种特殊的数据重组形式,可以返回底层数据的视图而不需要复制任何内容。数组拥有transpose方法,也有特殊的T属性
1 | arr = np.arange(15).reshape((3,5)) |
这里将横轴数轴进行了调换
对于更高维度的数组,transpose方法可以接收包含轴编号的元组:
1 | arr = np.arange(16).reshape((2,2,4)) |
这里的数据构于三维空间,0 1 2 3这样的四组数据沿第三轴分布。这里(0,1,2)表示将1,2轴进行互换,于是就得到了上面的结果。
还有一个swapaxes可用于接收一对轴号并对其进行重组,例如:arr.swapaxes(1,2)。这里不再给出具体例子。
注意:swapaxes返回的也是视图,并没有对数据进行复制