机器学习之Numpy-第1章ndarray多维数组对象

大兔子大兔子 提交于 2020-10-03 16:21:27

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位特殊情况。

  1. 根据条件创建布尔型索引
In [37]:
arr%2==1
Out[37]:
array([False,  True, False,  True, False,  True, False,  True, False,
        True])
 
  1. 索引与数组关联获取数据
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]]])

更多文章,请关注:
        

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!