NumPy一个很是重要的做用就是能够进行多维数组的操做,多维数组对象也叫作ndarray。咱们能够在ndarray的基础上进行一系列复杂的数学运算。python
本文将会介绍一些基本常见的ndarray操做,你们能够在数据分析中使用。数组
建立ndarray有不少种方法,咱们可使用np.random来随机生成数据:dom
import numpy as np # Generate some random data data = np.random.randn(2, 3) data
array([[ 0.0929, 0.2817, 0.769 ], [ 1.2464, 1.0072, -1.2962]])
除了随机建立以外,还能够从list中建立:3d
data1 = [6, 7.5, 8, 0, 1] arr1 = np.array(data1)
array([6. , 7.5, 8. , 0. , 1. ])
从list中建立多维数组:code
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]] arr2 = np.array(data2)
array([[1, 2, 3, 4], [5, 6, 7, 8]])
使用np.zeros建立初始值为0的数组:对象
np.zeros(10) array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
建立2维数组:教程
np.zeros((3, 6))
array([[0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.]])
使用empty建立3维数组:索引
np.empty((2, 3, 2))
array([[[0., 0.], [0., 0.], [0., 0.]], [[0., 0.], [0., 0.], [0., 0.]]])
注意,这里咱们看到empty建立的数组值为0,其实并非必定的,empty会从内存中随机挑选空间来返回,并不能保证这些空间中没有值。因此咱们在使用empty建立数组以后,在使用以前,还要记得初始化他们。
使用arange建立范围类的数组:内存
np.arange(15)
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
指定数组中元素的dtype:get
arr1 = np.array([1, 2, 3], dtype=np.float64) arr2 = np.array([1, 2, 3], dtype=np.int32)
能够经过data.shape得到数组的形状。
data.shape (2, 3)
经过ndim获取维数信息:
arr2.ndim 2
能够经过data.dtype得到具体的数据类型。
data.dtype dtype('float64')
在建立好一个类型的ndarray以后,还能够对其进行转换:
arr = np.array([1, 2, 3, 4, 5]) arr.dtype dtype('int64') float_arr = arr.astype(np.float64) float_arr.dtype dtype('float64')
上面咱们使用astype将int64类型的ndarray转换成了float64类型的。
若是转换类型的范围不匹配,则会自动进行截断操做:
arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1]) arr.astype(np.int32) array([ 3, -1, -2, 0, 12, 10], dtype=int32)
注意,这里是把小数截断,并无向上或者向下取整。
数组能够和常量进行运算,也能够和数组进行运算:
arr = np.array([[1., 2., 3.], [4., 5., 6.]]) arr * arr array([[ 1., 4., 9.], [16., 25., 36.]]) arr + 10 array([[11., 12., 13.], [14., 15., 16.]]) arr - arr array([[0., 0., 0.], [0., 0., 0.]]) 1 / arr array([[1. , 0.5 , 0.3333], [0.25 , 0.2 , 0.1667]]) arr ** 0.5 array([[1. , 1.4142, 1.7321], [2. , 2.2361, 2.4495]])
数组之间还能够进行比较,比较的是数组中每一个元素的大小:
arr2 = np.array([[0., 4., 1.], [7., 2., 12.]]) arr2 > arr array([[False, True, False], [ True, False, True]])
先看下index和切片的基本使用,index基本上和普通数组的使用方式是同样的,用来访问数组中某一个元素。
切片要注意的是切片后返回的数组中的元素是原数组中元素的引用,修改切片的数组会影响到原数组。
# 构建一维数组 arr = np.arange(10) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # index访问 arr[5] 5 # 切片访问 arr[5:8] array([5, 6, 7]) # 切片修改 arr[5:8] = 12 array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9]) # 切片能够修改原数组的值 arr_slice = arr[5:8] arr_slice[1] = 12345 arr array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9]) # 构建二维数组 arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) arr2d[2] array([7, 8, 9]) # index 二维数组 arr2d[0][2] 3 # index二维数组 arr2d[0, 2] 3 # 构建三维数组 arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) arr3d array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]]) # index三维数组 arr3d[0] array([[1, 2, 3], [4, 5, 6]]) # copy是硬拷贝,和原数组的值相互不影响 old_values = arr3d[0].copy() arr3d[0] = 42 arr3d array([[[42, 42, 42], [42, 42, 42]], [[ 7, 8, 9], [10, 11, 12]]]) arr3d[0] = old_values arr3d array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]]) # index 三维数组 arr3d[1, 0] array([7, 8, 9]) x = arr3d[1] x array([[ 7, 8, 9], [10, 11, 12]]) x[0] array([7, 8, 9])
slice还能够做为index使用,做为index使用表示的就是一个index范围值。
做为index表示的slice能够有多种形式。
有头有尾的,表示index从1开始到6-1结束:
arr[1:6]
array([ 1, 2, 3, 4, 64])
无头有尾的,表示index从0开始,到尾-1结束:
arr2d[:2]
array([[1, 2, 3], [4, 5, 6]])
有头无尾的,表示从头开始,到全部的数据结束:
arr2d[:2, 1:]
array([[2, 3], [5, 6]])
arr2d[1, :2]
array([4, 5])
index还可使用boolean值,表示是否选择这一个index的数据。
咱们先看下怎么构建一个boolean类型的数组:
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) names == 'Bob' array([ True, False, False, True, False, False, False])
上面咱们经过比较的方式返回了一个只包含True和False的数组。
这个数组能够做为index值来访问数组:
# 构建一个7 * 4 的数组 data = np.random.randn(7, 4) array([[ 0.275 , 0.2289, 1.3529, 0.8864], [-2.0016, -0.3718, 1.669 , -0.4386], [-0.5397, 0.477 , 3.2489, -1.0212], [-0.5771, 0.1241, 0.3026, 0.5238], [ 0.0009, 1.3438, -0.7135, -0.8312], [-2.3702, -1.8608, -0.8608, 0.5601], [-1.2659, 0.1198, -1.0635, 0.3329]]) # 经过boolean数组来访问: data[names == 'Bob'] array([[ 0.275 , 0.2289, 1.3529, 0.8864], [-0.5771, 0.1241, 0.3026, 0.5238]])
在索引行的时候,还能够索引列:
data[names == 'Bob', 3] array([0.8864, 0.5238])
能够用 ~
符号来取反:
data[~(names == 'Bob')] array([[-2.0016, -0.3718, 1.669 , -0.4386], [-0.5397, 0.477 , 3.2489, -1.0212], [ 0.0009, 1.3438, -0.7135, -0.8312], [-2.3702, -1.8608, -0.8608, 0.5601], [-1.2659, 0.1198, -1.0635, 0.3329]])
咱们能够经过布尔型数组设置值,在实际的项目中很是有用:
data[data < 0] = 0 array([[0.275 , 0.2289, 1.3529, 0.8864], [0. , 0. , 1.669 , 0. ], [0. , 0.477 , 3.2489, 0. ], [0. , 0.1241, 0.3026, 0.5238], [0.0009, 1.3438, 0. , 0. ], [0. , 0. , 0. , 0.5601], [0. , 0.1198, 0. , 0.3329]])
data[names != 'Joe'] = 7 array([[7. , 7. , 7. , 7. ], [0. , 0. , 1.669 , 0. ], [7. , 7. , 7. , 7. ], [7. , 7. , 7. , 7. ], [7. , 7. , 7. , 7. ], [0. , 0. , 0. , 0.5601], [0. , 0.1198, 0. , 0.3329]])
Fancy indexing也叫作花式索引,它是指使用一个整数数组来进行索引。
举个例子,咱们先建立一个 8 * 4的数组:
arr = np.empty((8, 4)) for i in range(8): arr[i] = i arr
array([[0., 0., 0., 0.], [1., 1., 1., 1.], [2., 2., 2., 2.], [3., 3., 3., 3.], [4., 4., 4., 4.], [5., 5., 5., 5.], [6., 6., 6., 6.], [7., 7., 7., 7.]])
而后使用一个整数数组来索引,那么将会以指定的顺序来选择行:
arr[[4, 3, 0, 6]] array([[4., 4., 4., 4.], [3., 3., 3., 3.], [0., 0., 0., 0.], [6., 6., 6., 6.]])
还可使用负值来索引:
arr[[-3, -5, -7]]
array([[5., 5., 5., 5.], [3., 3., 3., 3.], [1., 1., 1., 1.]])
花式索引还能够组合来使用:
arr = np.arange(32).reshape((8, 4)) arr
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23], [24, 25, 26, 27], [28, 29, 30, 31]])
上面咱们构建了一个8 * 4的数组。
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
array([ 4, 23, 29, 10])
而后取他们的第2列的第一个值,第6列的第三个值等等。最后获得一个1维的数组。
咱们能够在不一样维度的数组之间进行变换,还能够转换数组的轴。
reshape方法能够将数组转换成为任意的形状:
arr = np.arange(15).reshape((3, 5)) arr
array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
数组还提供了一个T命令,能够将数组的轴进行对调:
arr.T
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 array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) arr.transpose((1, 0, 2))
array([[[ 0, 1, 2, 3], [ 8, 9, 10, 11]], [[ 4, 5, 6, 7], [12, 13, 14, 15]]])
上面的transpose((1, 0, 2)) 怎么理解呢?
其含义是将x,y轴对调,z轴保持不变。
上面咱们经过使用reshape((2, 2, 4))方法建立了一个3维,也就是3个轴的数组。 其shape是 2 2 4 。
先看下对应关系:
(0,0)-》 [ 0, 1, 2, 3]
(0,1)-》 [ 4, 5, 6, 7]
(1,0)-》 [ 8, 9, 10, 11]
(1,1)-》 [12, 13, 14, 15]
转换以后:
(0,0)-》 [ 0, 1, 2, 3]
(0,1)-》 [ 8, 9, 10, 11]
(1,0)-》[ 4, 5, 6, 7]
(1,1)-》 [12, 13, 14, 15]
因而获得了咱们上面的的结果。
多维数组的轴转换可能比较复杂,你们多多理解。
还可使用 swapaxes 来交换两个轴,上面的例子能够重写为:
arr.swapaxes(0,1)
本文已收录于 http://www.flydean.com/09-python-numpy-ndarray/
最通俗的解读,最深入的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注个人公众号:「程序那些事」,懂技术,更懂你!