Numpy(Numerical Python的简称)是高性能科学计算和数据分析的基础包。它是所有高级工具的构建基础,Pandas就是构建在Numpy之上。
Numpy最重要的一个特点就是N维数组对象(ndarray),其是一个快速而灵活的大数据集容器。可以利用这个数组对整块数据执行一些数据运算,其语法和标量元素之间的运算类似。
ndarray是一个通用的同构数据多维容器,其中的所有元素必须是相同类型的。
1.创建ndarray
- 列表
In [1]:
import numpy as np data1 = [6,7,4,5,0,1,8] nda = np.array(data1) nda
Out[1]:
array([6, 7, 4, 5, 0, 1, 8])
- 嵌套列表
In [2]:
data2 = [[1,2,3],[4,5,6]] ndb = np.array(data2) ndb
Out[2]:
array([[1, 2, 3],
[4, 5, 6]])
除非显示说明,narray会尝试为新建的这个数组推断一个较为合适的数据类型。
- 每个数组都有一个shape(表示各维度大小的元组)
In [6]:
ndb.shape
Out[6]:
(2, 3)
- 和一个dtype(用于说明数组数据类型的对象)
In [12]:
ndb.dtype
Out[12]:
dtype('int64')
- 还有一些其他函数可以创建ndarray
In [9]:
np.ones([2,3],dtype='int64')
Out[9]:
array([[1, 1, 1],
[1, 1, 1]])
In [4]:
np.zeros([2,3])
Out[4]:
array([[0., 0., 0.],
[0., 0., 0.]])
1.1.数据创建函数
| 函数 | 说明 |
|---|---|
| array | 将输入数据(列表,元组,数组或其他序列类型)转换为ndarray。要么推断出dtype,要么显示指定dtype。默认直接复制输入数据。 |
| asarray | 将输入转换为ndarray,如果输入本身就是yigendarray就不进行复制。 |
| arange | 类似于内置的rangge,但是返回一个ndarray而不是列表 |
| ones,ones_like | 根据指定的形状和dtype创建一个全1数组。ones_like以另一个数组为参考,并根据其形状和dtype创建一个全1数组。 |
| zeros,zeros_like | 类似于ones和ones_like,只不过产生的全是0数组而已 |
| empty,empty_like | 创建新数组,只分配内存空间但不填充任何值。 |
| eye,identity | 创建一个正方的N*N单位矩阵(对角线为1,其余为0) |
ndarray的数据类型
dtype(数据类型)是一个特殊的对象,它包含有ndarray将一块内存解释为特定数据类型所需的信息。
In [1]:
import numpy as np arr1 = np.array([1,2,3],dtype=np.float64) arr2 = np.array([1,2,3],dtype=np.int64) arr1.dtype
Out[1]:
dtype('float64')
In [2]:
arr2.dtype
Out[2]:
dtype('int64')
| 类型 | 类型代码 | 说明 |
|---|---|---|
| int8,uint8 | i1,u1 | 有符号和无符号的8位(1个字节)整型 |
| int16,uint16 | i2,u2 | 有符号和无符号的16位(2个字节)整型 |
| int32,uint32 | i4,u4 | 有符号和无符号的32位(4个字节)整型 |
| int64,uint64 | i8,u8 | 有符号和无符号的64位(8个字节)整型 |
| float16 | f2 | 半精度浮点数 |
| float32 | f4或f | 标准的单精度浮点数,与C的float兼容 |
| float64 | f8或d | 标准的双精度浮点数,与C的double和Python的float对象兼容 |
| float128 | f16或g | 扩展精度浮点数 |
| complex64,complex128,complex256 | c8,c16,c32 | 分别用两个32位,64位或128位浮点数标识的复数 |
| bool | ? | 存储True和False值的布尔类型 |
| object | O | Python对象类型 |
| string_ | S | 固定长度的字符串类型(每个字符串一个字节)。例如要创建一个长度为10的字符串,应使用S10 |
| unicode_ | U | 固定长度的Unicode类型(字节数由平台决定)根字符串的定义方式一样(如U10) |
In [5]:
import numpy as np arr1 = np.array([1,2,3],dtype='S2') arr2 = np.array([1,2,3],dtype='i4') arr1
Out[5]:
array([b'1', b'2', b'3'], dtype='|S2')
In [6]:
arr1[1]
Out[6]:
b'2'
- 可以通过astype显式的转换其dtype
In [7]:
arr1.astype('u4')
Out[7]:
array([1, 2, 3], dtype=uint32)
3.数组和标量之间的运算
在运用数组计算,可以不必编写循环即可对数据进行匹配处理,这就是矢量化。
- 大小相同的数组之间的任何运算都会将运算应用到每个元素上。
In [6]:
import numpy as np arr = np.array([1,2,3]) arr1 = np.array([2,3,4]) arr+arr1
Out[6]:
array([3, 5, 7])
In [7]:
arr*0.5
Out[7]:
array([0.5, 1. , 1.5])
In [8]:
arr**0.5
Out[8]:
array([1. , 1.41421356, 1.73205081])
- 不同大小的数组之间的运算叫广播。
4.索引和切片
注意:
这里的切片与list的切片的区别。
- list 切片返回的是不原数据,对新数据的修改不会影响原数据
- NumPy.ndarry 的切片返回的是原数据,对切片修改会影响原数据,若希望得到原数据的副本, 可以用 copy()
In [11]:
import numpy as np arr = np.arange(10) arr
Out[11]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [13]:
arr[5]
Out[13]:
5
In [15]:
arr[0:5]
Out[15]:
array([0, 1, 2, 3, 4])
- 当将一个标量赋值给切片时,该值会自动传播,也就是广播。这里和列表的区别就是,数组切片时原始的视图,任何修改都会改变到源数组上。
In [17]:
arr[0:5]=10 arr
Out[17]:
array([10, 10, 10, 10, 10, 5, 6, 7, 8, 9])
这里涉及的目的是:因为Numpy是为了处理大数据量的,如果发生复制等事情,则会造成大量内存的使用。
4.1.高维数组
这里演示的是创建二维数组,高阶类似。
- 整数随机数组
In [18]:
import numpy as np arr = np.random.randint(0,10,size=[3,3]) arr
Out[18]:
array([[3, 1, 0],
[2, 3, 4],
[7, 3, 8]])
- 小数多维数组
In [20]:
arr1= np.random.random((3,3)) arr1
Out[20]:
array([[0.45444967, 0.55649903, 0.98066105],
[0.04549819, 0.41755054, 0.39653621],
[0.67820675, 0.50842123, 0.15909352]])
- 生成符合正态分布的随机数
In [31]:
arr3 = np.random.randn(4,3) arr3
Out[31]:
array([[ 0.12253952, 0.93764629, -1.10739373],
[-0.14677255, 2.22531292, 1.25376962],
[ 1.75692968, 1.06357339, -1.39978643],
[-1.27281238, 2.12064567, 0.45897216]])
- 只使用一个维度,则可以降低维度
In [22]:
arr[1]
Out[22]:
array([2, 3, 4])
- 取单个元素
In [26]:
arr[1][2]
Out[26]:
4
- 切片,只针对第一维
In [24]:
arr[:2]
Out[24]:
array([[3, 1, 0],
[2, 3, 4]])
- 切片,针一维和二维,中间逗号分隔
In [27]:
arr[:2,:2]
Out[27]:
array([[3, 1],
[2, 3]])
- 标量复制
In [29]:
arr[:2]=9 arr
Out[29]:
array([[9, 9, 9],
[9, 9, 9],
[7, 3, 8]])
4.2.布尔型索引
In [32]:
import numpy as np arr = np.arange(10) arr
Out[32]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
选出奇数项,0位特殊情况。
- 根据条件创建布尔型索引
In [37]:
arr%2==1
Out[37]:
array([False, True, False, True, False, True, False, True, False,
True])
- 索引与数组关联获取数据
In [38]:
arr[arr%2==1]
Out[38]:
array([1, 3, 5, 7, 9])
- 多维数组
In [48]:
import numpy as np arr1 = np.random.randint(0,10,size=[3,3]) arr1
Out[48]:
array([[2, 3, 0],
[1, 2, 5],
[3, 7, 3]])
In [49]:
arr2 = np.array([1,2,2])
In [50]:
arr1[arr2==2]
Out[50]:
array([[1, 2, 5],
[3, 7, 3]])
In [52]:
arr1[arr2==2,:2]
Out[52]:
array([[1, 2],
[3, 7]])
- 布尔型数组的长度必须和被索引的轴长度一致。
- 除了==号,还可以使用,不等号(!=),负号(-)对条件进行否定
- 使用 & (和),| (或)等布尔运算
在机器学习中常用的是将部分值处理为0
In [54]:
import numpy as np arr3 = np.random.randn(4,3) arr3
Out[54]:
array([[-0.22936582, 0.22714778, -1.20923907],
[ 0.00211171, 0.73835705, 0.07444639],
[ 0.1406557 , -0.8766863 , 0.25614127],
[-0.31704606, -0.39800804, -1.13511035]])
In [57]:
arr3[arr3<0]=0 arr3
Out[57]:
array([[0. , 0.22714778, 0. ],
[0.00211171, 0.73835705, 0.07444639],
[0.1406557 , 0. , 0.25614127],
[0. , 0. , 0. ]])
4.3.花式索引
花式索引是一个NumPy术语,是指利用整数数组进行索引。也可以理解为以特定的顺序选取子集。
花式索引和切片不一样,总是将数据复制到新数组中。
- 一维
In [3]:
import numpy as np arr1 = np.array(['a','b','c','d','e','f','g','h','i']) arr1
Out[3]:
array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], dtype='<U1')
In [4]:
arr1[[4,1,7,5]]
Out[4]:
array(['e', 'b', 'h', 'f'], dtype='<U1')
- 二维
In [6]:
import numpy as np arr = np.random.randn(10,3) arr
Out[6]:
array([[ 0.57989704, 1.05941762, -1.236248 ],
[-0.49258106, 1.34762204, -0.55370729],
[-0.98801594, 0.55040551, -0.31393819],
[-1.2883949 , -1.85313486, 0.2451353 ],
[ 1.29845609, 0.10674859, 1.4505412 ],
[-0.0586313 , 0.90021843, 1.75536925],
[ 0.16780398, -0.06483459, -1.21850008],
[-3.13836877, 0.02792063, -0.16427975],
[ 1.3108984 , -0.0197715 , 0.98607566],
[-0.04675146, -1.04485198, -0.76184571]])
In [7]:
arr[[4,1,7,5]]
Out[7]:
array([[ 1.29845609, 0.10674859, 1.4505412 ],
[-0.49258106, 1.34762204, -0.55370729],
[-3.13836877, 0.02792063, -0.16427975],
[-0.0586313 , 0.90021843, 1.75536925]])
- 传入多个数组
In [13]:
import numpy as np arr1 = np.arange(32).reshape((8,4)) arr1
Out[13]:
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]])
In [14]:
arr1[[4,1,7,5]]
Out[14]:
array([[16, 17, 18, 19],
[ 4, 5, 6, 7],
[28, 29, 30, 31],
[20, 21, 22, 23]])
In [16]:
arr1[[4,1,7,5],[0,3,1,2]]
Out[16]:
array([16, 7, 29, 22])
观察以上两个输出,第二个数组是对第一个数组的索引结果在此进行索引。
In [17]:
arr1[np.ix_([4,1,7,5],[0,3,1,2])]
Out[17]:
array([[16, 19, 17, 18],
[ 4, 7, 5, 6],
[28, 31, 29, 30],
[20, 23, 21, 22]])
此时使用np.ix_函数,第二个数组会应用到第一个数组结果的每一项中。
4.4.数组转置
- 二维
In [18]:
import numpy as np arr = np.arange(15).reshape(3,5) arr
Out[18]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
In [19]:
arr.T
Out[19]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
在后续的矩阵计算中经常使用。例如:利用np.dot计算矩阵内积xTxxTx
In [20]:
np.dot(arr.T,arr)
Out[20]:
array([[125, 140, 155, 170, 185],
[140, 158, 176, 194, 212],
[155, 176, 197, 218, 239],
[170, 194, 218, 242, 266],
[185, 212, 239, 266, 293]])
- 多维
In [25]:
import numpy as np arr = np.arange(30).reshape(2,5,3) arr
Out[25]:
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]]])
In [26]:
arr.T
Out[26]:
array([[[ 0, 15],
[ 3, 18],
[ 6, 21],
[ 9, 24],
[12, 27]],
[[ 1, 16],
[ 4, 19],
[ 7, 22],
[10, 25],
[13, 28]],
[[ 2, 17],
[ 5, 20],
[ 8, 23],
[11, 26],
[14, 29]]])
更多文章,请关注:
来源:oschina
链接:https://my.oschina.net/u/3275937/blog/4298224