我的知识记录

digSelf

机器学习基础:Numpy数组的创建和基本使用

2021-10-26
机器学习基础:Numpy数组的创建和基本使用

在机器学习中,不可避免的要与数据打交道。如何高效的处理计算就是一个非常严肃的问题,幸运的是,NumPy就是一个高效的科学计算方案,因此学习和使用NumPy是非常必要的。

NumPy 数组的创建与初始化

学习的目标是:

  • 关于NumPy数组的相关知识
  • 如何创建和初始化NumPy数组

Arrays

Numpy中的数组类似于Python中的list,但是却又添加了新的特性。可以使用np.array函数将python中的list转换为NumPy的数组。np.array函数具有一系列的参数,其中比较重要的就是dtype参数。dtype参数用来指定NumPy数组保存的元素的数据类型。

import numpy as np

arr = np.array([[0, 1, 2], [3, 4, 5]],
               dtype=np.float32)
print(repr(arr))

上述代码创建了一个二维矩阵,这个二维矩阵的元素类型指定为np.float32类型。

Numpy数组允许数组中的元素是混合类型的。如果保存的元素是混合类型的话,NumPy数组会自动进行向上转型——转换为数组当中的表示范围最大的元素的数据类型。举个例子,如果数组中是intfloat元素的混合,那么数组中的元素统一向上转型为float类型;如果数组中的元素是intfloat以及string的混合数据,那么元素类型会统一的向上转型为string类型。

Copying

当我们想要拷贝一个由np.array创建出来的数组,不能简单的进行赋值操作,原因是这样进行操作传递过去的是引用而不是按值拷贝,因此需要使用array对象的内置函数copy来进行拷贝:

a = np.array([0, 1])
b = np.array([9, 8])
c = a
print('Array a: {}'.format(repr(a)))
c[0] = 5
print('Array a: {}'.format(repr(a)))

d = b.copy()
d[0] = 6
print('Array b: {}'.format(repr(b)))

Casting

当我们想要转换NumPy数组中元素的类型时,可以使用NumPy数组对象的内置函数astype来达成上述目的:

arr = np.array([0, 1, 2])
print(arr.dtype)
arr = arr.astype(np.float32)
print(arr.dtype)

NaN and Infinity

当我们不想在NumPy数组中的特定索引处存放一个数值时,可以使用np.nan来做占位。注意,np.nan不是一个数,因此他不能作为整数存放。

arr = np.array([np.nan, 1, 2])
print(repr(arr))

arr = np.array([np.nan, 'abc'])
print(repr(arr))

# Will result in a ValueError
np.array([np.nan, 1, 2], dtype=np.int32)

当我们想表达无穷时,可以使用np.inf表示正无穷,注意:np.inf不能被转为整型

print(np.inf > 1000000)

arr = np.array([np.inf, 5])
print(repr(arr))

arr = np.array([-np.inf, 1])
print(repr(arr))

# Will result in an OverflowError
np.array([np.inf, 3], dtype=np.int32)

Numpy 数组的基础操作

Ranged Data

使用np.array创建NumPy数组相当于使用硬编码的方式来创建一个数组对象,当数组中需要存放大量数据的时候,上述操作就不再实用了。因此np.arange就诞生了,用来创建范围数据。它的使用方式与python中的range操作是一致的,且它只会返回一位数组。

arr = np.arange(5)
print(repr(arr))

arr = np.arange(5.1)
print(repr(arr))

arr = np.arange(-1, 4)
print(repr(arr))

arr = np.arange(-1.5, 4, 2)
print(repr(arr))

需要注意:

  • np.arange使用的是左闭右开的区间来表示范围的,即:[0, n)
  • np.arangenp.array一样,可以向上转型,以及可以使用dtype来手动转换元素的类型

如果需要指定在返回的数组中的元素个数来生成数组而不是使用步长来生成数组,可以使用np.linspace函数来达成上述目的。

np.linspace的前两个参数分别是范围的起始值和终止值(注意还是左闭右闭而不是左闭右开的),如果不想包含终止值,使用endpoint=False参数来排除掉该点。使用num参数来指定在数组中生成多少个元素,默认值是50。同时,它也提供dtype来手动转型。

arr = np.linspace(5, 11, num=4)
print(repr(arr))

arr = np.linspace(5, 11, num=4, endpoint=False)
print(repr(arr))

arr = np.linspace(5, 11, num=4, dtype=np.int32)
print(repr(arr))

Reshaping Data

如果想重新设置数组的格式(形状),可以使用np.reshape函数来达到目的。它有两个参数,分别是:

  • 想要重新格式化形状的数组对象
  • 想要格式化成的形状信息

需要注意:新格式化的形状,必须要包含且刚好包含格式化之前的元素。比如12个元素构成的数组,它可以格式化为(3, 4)(4, 3),但是不能格式化为(4, 4)

在想要格式化的形状中,允许有一个维度填写为-1。填写为-1的那个维度,将根据剩下的维度自动进行计算出合适的值填入(与C语言中,二维数组在静态创建和初始化时允许第一个维度为空一样)

arr = np.arange(8)

reshaped_arr = np.reshape(arr, (2, 4))
print(repr(reshaped_arr))
print('New shape: {}'.format(reshaped_arr.shape))

reshaped_arr = np.reshape(arr, (-1, 2, 2))
print(repr(reshaped_arr))
print('New shape: {}'.format(reshaped_arr.shape))

np.array对象提供了将多维数组格式化为一维数组的内置函数,它是flatten,可以使用点语法进行调用

arr = np.arange(8)
arr = np.reshape(arr, (2, 4))
flattened = arr.flatten()
print(repr(arr))
print('arr shape: {}'.format(arr.shape))
print(repr(flattened))
print('flattened shape: {}'.format(flattened.shape))

Transposing

在进行科学计算的时候,经常需要将数据转置,NumPy也提供了转置的函数np.transpose

arr = np.arange(8)
arr = np.reshape(arr, (4, 2))
transposed = np.transpose(arr)
print(repr(arr))
print('arr shape: {}'.format(arr.shape))
print(repr(transposed))
print('transposed shape: {}'.format(transposed.shape))

np.transpose提供了一个参数axes,用来指定如何交换这些轴上的所代表的数据,如:

arr = np.arange(24)
arr = np.reshape(arr, (3, 4, 2))
transposed = np.transpose(arr, axes=(1, 2, 0))
print('arr shape: {}'.format(arr.shape))
print('transposed shape: {}'.format(transposed.shape))

0,1,2分别代表第一个坐标轴,第二个坐标轴和第三个坐标轴。当指定axes参数为(1, 2, 0)后,代表原来数据的第一个坐标轴变为新数组中的第三个坐标轴;其他两个位置以此类推。对于np.transpose的三维数组的axes的默认值是(2, 1, 0),即:翻转。

Zeros and Ones

有的时候我们需要创建只包含0或者1的数组,可以使用np.zerosnp.ones来创建出Numpy数组对象。

arr = np.zeros(4)
print(repr(arr))

arr = np.ones((2, 3))
print(repr(arr))

arr = np.ones((2, 3), dtype=np.int32)
print(repr(arr))

如果想创建和已经存在的数组同样形状的只包含0或者1的数组,可以使用np.zeros_like以及np.ones_like完成上述目的:

arr = np.array([[1, 2], [3, 4]])
print(repr(np.zeros_like(arr)))

arr = np.array([[0., 1.], [1.2, 4.]])
print(repr(np.ones_like(arr)))
print(repr(np.ones_like(arr, dtype=np.int32)))

需要注意,只要是NumPy的数组对象,在创建时基本上都可以使用dtype来手动指定元素的初始类型

  • 0