NumPy 的ndarray:一种多维数组对象
该对象是一个快速且灵活的大数据容器,可以利用这种数组对整个数据进行科学计算,语法跟标量元素之间的计算一样。
创建ndarray的方法:
array函数:它接受一些序列型的对象,然后产生一个含有传入数据的numpy数组。
1 import numpy as np 2 3 data1 = [1,3,6.5,3] 4 data2 = [[1,3,5,7,9],[2,4,6,8,10]] 5 np_data = np.array(data1) 6 np_data2 = np.array(data2) 7 print("维度",np_data.ndim) 8 print("数据类型",np_data.dtype) 9 print("各维度大小",np_data.shape) 10 print("array1",np_data) 11 print("array2",np_data2) 12 print("维度",np_data2.ndim) 13 print("数据类型",np_data2.dtype) 14 print("各维度大小",np_data2.shape) 15 16 17 18 ##### 19 维度 1 20 数据类型 float64 21 各维度大小 (4,) 22 array1 [1. 3. 6.5 3. ] 23 array2 [[ 1 3 5 7 9] 24 [ 2 4 6 8 10]] 25 维度 2 26 数据类型 int32 27 各维度大小 (2, 5)
zeros ,ones 可以创指定维度和形状的全0或全1 的数组。empty可以创建没有具体任何数组的数组。
1 np_data = np.zeros(10) 2 np_data2 = np.ones((3,4)) 3 4 5 print("array1",np_data) 6 print("维度",np_data.ndim) 7 print("数据类型",np_data.dtype) 8 print("各维度大小",np_data.shape) 9 10 print("array2",np_data2) 11 print("维度",np_data2.ndim) 12 print("数据类型",np_data2.dtype) 13 print("各维度大小",np_data2.shape) 14 15 16 ####print#### 17 18 array1 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 19 维度 1 20 数据类型 float64 21 各维度大小 (10,) 22 array2 [[1. 1. 1. 1.] 23 [1. 1. 1. 1.] 24 [1. 1. 1. 1.]] 25 维度 2 26 数据类型 float64 27 各维度大小 (3, 4)
1 np_data3 = np.empty((2,3,2)) 2 print("array3",np_data3) 3 print("维度",np_data3.ndim) 4 print("数据类型",np_data3.dtype) 5 print("各维度大小",np_data3.shape) 6 7 8 array3 [[[8.82769181e+025 7.36662981e+228] 9 [7.54894003e+252 2.95479883e+137] 10 [1.42800637e+248 2.64686750e+180]] 11 12 [[1.09936856e+248 6.99481925e+228] 13 [7.54894003e+252 7.67109635e+170] 14 [2.64686750e+180 5.63234836e-322]]] 15 维度 3 16 数据类型 float64 17 各维度大小 (2, 3, 2)
empty产生的是未初始化的垃圾数值
arange是python内置函数range的数组版本
In [1]: import numpy as np In [2]: np.arange(10) Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
eye和identity 创建一个正方形的N*N的单位矩阵
1 In [3]: np.eye(3) 2 Out[3]: 3 array([[1., 0., 0.], 4 [0., 1., 0.], 5 [0., 0., 1.]]) 6 7 8 In [5]: np.identity(3) 9 Out[5]: 10 array([[1., 0., 0.], 11 [0., 1., 0.], 12 [0., 0., 1.]])
ndarray 的数据类型:
NumPy的数据类型:
类型 | 类型说明 |
int8,uint8 | 有符号和无符号的8位(1个字节)整型 |
int16,uint16 | 有符号和无符号的16位(2个字节)整型 |
int32,uint32 | 有符号和无符号的32位(3个字节)整型 |
int64,uint64 | 同上类似 |
float16 | 半精度浮点数 |
float32 | 标准的单精度浮点数 |
float64 | |
float128 | |
complex64,complex128,complexu256 | 分别用两个32位、64位、128位浮点数表示的复数 |
bool | 布尔类型 |
object | python对象类型 |
string_ | 固定长度的字符串类型(每个字符1个字节) |
unicode_ | 固定长度的unicode类型(字节数由平台数而定) |
可以通过astype进行显示的转换
1 In [35]: arr = np.array([1,2,3,4,5]) 2 3 In [36]: arr.dtype 4 Out[36]: dtype('int32') 5 6 In [37]: folat_arr = arr.astype(np.float64) 7 8 9 In [39]: float_arr = arr.astype(np.float64) 10 11 In [40]: float_arr 12 Out[40]: array([1., 2., 3., 4., 5.]) 13 14 In [41]: float_arr.dtype 15 Out[41]: dtype('float64')
需要注意的是:调用astype始终会创建一个新的数组(原始数据的一份拷贝)
数组和标量之间的运算
数组可以矢量化。大小相等的数组之间的任何运算都是元素级的,数组与标量的运算会传播到各个元素。
1 In [42]: arr = np.array([[1,2,3],[4,5,6]]) 2 3 In [43]: arr 4 Out[43]: 5 array([[1, 2, 3], 6 [4, 5, 6]]) 7 8 In [44]: arr*arr 9 Out[44]: 10 array([[ 1, 4, 9], 11 [16, 25, 36]]) 12 13 In [45]: arr*2 14 Out[45]: 15 array([[ 2, 4, 6], 16 [ 8, 10, 12]])
基本的索引和切片
与python的list的索引和切片类似
但需要注意的是数组切片是原始数组的试图,并不是像list一样是数据的复制。
In [46]: arr = np.arange(10) In [47]: arr Out[47]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [48]: arr_slice = arr[5:8] In [50]: arr_slice[2] =12 In [51]: arr Out[51]: array([ 0, 1, 2, 3, 4, 5, 6, 12, 8, 9])
如果要拷贝一份副本而不是试图,需要显式复制 arr.copy()
访问多维数组的元素:arr[0][1]
可以一次传入多个切片
In [52]: arr = np.array([[1,2,3],[4,5,6]]) In [53]: arr[:1,1:] Out[53]: array([[2, 3]]) In [54]: arr[1,:2] Out[54]: array([4, 5])
布尔型索引
In [55]: names = np.array(['Bob','Joe','Will','Bob','will']) In [56]: names Out[56]: array(['Bob', 'Joe', 'Will', 'Bob', 'will'], dtype='<U4') In [62]: data = np.random.randn(5,4) In [63]: data[names=='Bob'] #names = 'Bob'产生一个布尔类型数组,这个数组可以作为索引使用,这个数组的长度,必须跟被索引的数组的轴长度一致 Out[63]: array([[-1.79012449, -0.01804037, 0.43492455, -1.35150168], [ 0.75883679, -0.34051626, 0.10205794, 0.39826656]])
要选取除‘Bob’以外的值,可以使用不等号 !=
In [64]: data[names!='Bob'] Out[64]: array([[ 0.73624561, -0.2467165 , 0.72230317, 0.50554012], [ 0.39531108, 0.89543353, 0.30720349, -1.1979887 ], [-0.57461644, 0.66571736, 0.50462228, 0.10375058]])
选取多个条件,可以进行与或运算(& ,|)
In [67]: data[(names =='Bob')| (names =="Will")] Out[67]: array([[-1.79012449, -0.01804037, 0.43492455, -1.35150168], [ 0.39531108, 0.89543353, 0.30720349, -1.1979887 ], [ 0.75883679, -0.34051626, 0.10205794, 0.39826656]])
花式索引:它是指利用整数的数组进行索引。
arr =np.empty((8,4)) In [70]: for i in range(8): ...: arr[i] = i+10 ...: In [71]: arr Out[71]: array([[10., 10., 10., 10.], [11., 11., 11., 11.], [12., 12., 12., 12.], [13., 13., 13., 13.], [14., 14., 14., 14.], [15., 15., 15., 15.], [16., 16., 16., 16.], [17., 17., 17., 17.]]) #通过花式索引取值 In [72]: arr[[4,3,0,6]] Out[72]: array([[14., 14., 14., 14.], [13., 13., 13., 13.], [10., 10., 10., 10.], [16., 16., 16., 16.]])
#通过负数索引从后向前取值
In [73]: arr[[-4,-3,-6]]
Out[73]:
array([[14., 14., 14., 14.],
[15., 15., 15., 15.],
[12., 12., 12., 12.]])
数组转置和轴交换:
T属性:
T属性相当于求转置矩阵
1 In [74]: arr = np.arange(15).reshape(3,5) 2 3 In [75]: arr 4 Out[75]: 5 array([[ 0, 1, 2, 3, 4], 6 [ 5, 6, 7, 8, 9], 7 [10, 11, 12, 13, 14]]) 8 9 In [76]: arr.T 10 Out[76]: 11 array([[ 0, 5, 10], 12 [ 1, 6, 11], 13 [ 2, 7, 12], 14 [ 3, 8, 13], 15 [ 4, 9, 14]])
transpose 方法:根据轴的索引进行转置,举例说明:arr_T中数值5 的索引元祖是(0,1,3),tanspose(1,0,2)相当于根据索引重新定义索引元祖为(1,0,3)
1 In [78]: arr_t = np.arange(16).reshape(2,2,4) 2 3 In [79]: arr_t 4 Out[79]: 5 array([[[ 0, 1, 2, 3], 6 [ 4, 5, 6, 7]], 7 8 [[ 8, 9, 10, 11], 9 [12, 13, 14, 15]]]) 10 11 In [80]: arr_t.transpose(1,0,2) 12 Out[80]: 13 array([[[ 0, 1, 2, 3], 14 [ 8, 9, 10, 11]], 15 16 [[ 4, 5, 6, 7], 17 [12, 13, 14, 15]]])
swapaxes方法
In [81]: name = ['John','David','Rose','Jack'] In [82]: age = [12,23,44,22] In [88]: person = [name,age] In [89]: person =np.array(person) In [90]: person Out[90]: array([['John', 'David', 'Rose', 'Jack'], ['12', '23', '44', '22']], dtype='<U5') In [91]: person.swapaxes(0,1) Out[91]: array([['John', '12'], ['David', '23'], ['Rose', '44'], ['Jack', '22']], dtype='<U5') In [92]: