1.数组算术:
ndarray数组允许进行批量操作而无需使用for循环,因此更加简便,这种特性也被称为向量化。任何两个等尺寸之间的算术操作都应用逐元素操作的方式进行。
import numpy as np
arr1 = np.array([[1,2,3,4],[9,8,7,6]])
arr2 = np.array([[4,3,2,1],[6,7,8,9]])
arr1 + arr2
Out[4]:
array([[ 5, 5, 5, 5],
[15, 15, 15, 15]])
arr1 * arr2
Out[5]:
array([[ 4, 6, 6, 4],
[54, 56, 56, 54]])
1 / arr1
Out[6]:
array([[1. , 0.5 , 0.33333333, 0.25 ],
[0.11111111, 0.125 , 0.14285714, 0.16666667]])
arr2 * 0.8
Out[7]:
array([[3.2, 2.4, 1.6, 0.8],
[4.8, 5.6, 6.4, 7.2]])
同尺度数组之间的比较,会产生一个布尔型数组。
arr1 > arr2
Out[8]:
array([[False, False, True, True],
[ True, True, False, False]])
上述操作均是在同尺度数组之间进行的,对于不同尺度数组间的操作,会使用到广播特性。
2.数组索引与切片:
索引:获取数组中特定位置元素的过程;
切片:获取数组元素子集的过程。
- 一维数组的索引和切片:与python的列表类似
- 多维数组的索引:
- 多维数组的切片:
TIPS:数组切片是原始数组的视图。这意味着数据不会被复制,对视图的任何修改都会反映在源数组上。之所以这样设计是因为NumPy被设计成能够处理非常大的数组,如果NumPy操作总是复制数据,会导致性能和内存问题。如果你需要数组的切片拷贝而不是一个视图时,需要使用copy()方法显式地复制。
arr = np.arange(10)
arr
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr[::2]
# array([0, 2, 4, 6, 8])
arr[::2] = 99
arr
# array([99, 1, 99, 3, 99, 5, 99, 7, 99, 9])
3.数组的变换:
- ndarray数组的维度变换方法:
函数 | 说明 |
---|---|
.reshape(shape) | 不改变数组元素,返回一个shape形状的数组,原数组不变 |
.resize(shape) | 与.reshape()功能一致,但修改原数组 |
.swapaxes(ax1,ax2) | 将数组n个维度中两个维度进行调换 |
.flatten() | 对数组进行降维,返回折叠后的一维数组,原数组不变 |
a = np.ones((2,3,4),dtype=np.int32)
a
Out[10]:
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]])
a.reshape((3,8))
Out[11]:
array([[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]])
a
Out[12]:
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]])
a.resize((3,8))
a
Out[14]:
array([[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]])
a.flatten()
Out[15]:
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1])
a
Out[16]:
array([[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]])
- ndarray数组的类型变换方法:
new_a = a.astype(new_type)
astype()方法一定会创建新的数组(原始数据的一个拷贝),即使两个类型一致。
a = np.ones((2,3,4),dtype=np.int32)
a
Out[18]:
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]])
b = a.astype(np.float)
b
Out[20]:
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]])
- ndarray数组向列表的转换:
ls = a.tolist()
a = np.full((2,3,4),25,dtype=np.int32)
a
Out[22]:
array([[[25, 25, 25, 25],
[25, 25, 25, 25],
[25, 25, 25, 25]],
[[25, 25, 25, 25],
[25, 25, 25, 25],
[25, 25, 25, 25]]])
a.tolist()
Out[23]:
[[[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]],
[[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]]]
4.数组转置与换轴:
转置是一种特殊的数据重组形式,可以返回底层数据的视图而不需要复制任何内容。
数组拥有transpose
方法,也有特殊的T
属性。
arr = np.arange(15).reshape((3,5))
arr
Out[33]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
arr.transpose
Out[34]: <function ndarray.transpose>
arr.T
Out[35]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
对于更高纬度的数组,transpose
方法可以接受包含轴编号的元组,用于转置轴。
arr = np.arange(16).reshape((2,2,4))
arr
Out[37]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
# 下面的操作是将原来的第二个轴变为第一个,原来的第一个轴变为第二个轴,最后一个轴不变
arr.transpose((1,0,2))
Out[38]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
ndarray的swapaxes
方法,通过接受一对轴编号作为参数,并对轴进行调整用于重组数据。swapaxes
方法返回的是数据的视图,而没有对数据进行复制。
arr = np.arange(16).reshape((2,2,4))
arr
Out[44]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
arr.swapaxes(1,2)
Out[45]:
array([[[ 0, 4],
[ 1, 5],
[ 2, 6],
[ 3, 7]],
[[ 8, 12],
[ 9, 13],
[10, 14],
[11, 15]]])
arr.shape
Out[46]: (2, 2, 4)
arr.swapaxes(1,2).shape
Out[47]: (2, 4, 2)
Reference:
《Python for Data Analysis:Data Wrangling with Pandas,Numpy,and IPython》