ndarray的创建

可以使用array函数从常规Python列表或元组中创建数组。得到的数组的类型是从Python列表中元素的类型推导出来的。
创建数组最简单的办法就是使用array函数。它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的numpy数组。其中,嵌套序列(比如由一组等长列表组成的列表)将会被转换为一个多维数组。

  1. # 创建一个一维数组
  2. a = np.array([1, 2, 3])
  3. # 创建一个多维数组
  4. a = np.array([[1, 2], [3, 4]])
  5. # 最小维度
  6. a = np.array([1, 2, 3, 4, 5], ndmin=2)
  7. # [[1 2 3 4 5]]
  8. # 将元组转换为数组
  9. a = np.array(((1,2,3), (4,5,6)))
  10. type(a) # numpy.ndarray

创建指定类型的数组

默认情况下,创建的数组的dtype是 float64 类型的。

可以通过dtype参数指定数组中元素的类型:

  1. # dtype参数
  2. a = np.array([1, 2, 3], dtype=complex)
  1. [1.+0.j 2.+0.j 3.+0.j]

创建具有初始占位符内容的数组

通常,数组的元素最初是未知的,但它的大小是已知的。因此,NumPy提供了几个函数来创建具有初始占位符内容的数组。

  • zeros() 可以创建指定长度或者形状的全0数组
  • ones() 可以创建指定长度或者形状的全1数组
  • empty() 创建一个数组,其初始内容是随机的,取决于内存的状态
  • eye() 创建一个单位矩阵
  • diag() 创建一个对角矩阵

举例:

生成全是0的3x3矩阵

  1. np.zeros([3,3])
  1. array([[0., 0., 0.],
  2. [0., 0., 0.],
  3. [0., 0., 0.]])

生成全是1的3x3矩阵

  1. np.ones([3,3])
  1. array([[1., 1., 1.],
  2. [1., 1., 1.],
  3. [1., 1., 1.]])

生成3阶的单位矩阵

  1. np.eye(3)
  1. array([[1., 0., 0.],
  2. [0., 1., 0.],
  3. [0., 0., 1.]])

生成3阶对角矩阵

  1. np.diag([1, 2, 3])
  1. array([[1, 0, 0],
  2. [0, 2, 0],
  3. [0, 0, 3]])

创建指定范围的数组

arange

为了创建数字组成的数组,NumPy提供了一个类似于range的函数,该函数返回数组而不是列表。

arange 定义如下:

  1. numpy.arange([start, ]stop, [step, ]dtype=None)

举例:

  1. np.arange(10) # 默认起始为 0
  2. # 输出: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  3. np.arange(0,10) # 区间 [0,10)
  4. # 输出: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  5. np.arange(1, 4, 0.5) # 指定步长为 0.5,不包括 4
  6. # 输出: array([1. , 1.5, 2. , 2.5, 3. , 3.5])
  7. np.arange(10, 31, 5) # 起始为10,指定步长为 5,不包括 31
  8. # 输出: array([10 15 20 25 30])
  9. np.arange(9, -1, -1) # 步长为负, 倒序生成
  10. # 输出: array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

linspace

当arange与浮点参数一起使用时,由于有限的浮点精度,通常不可能预测所获得的元素的数量。出于这个原因,通常最好使用 linspace 函数来接收我们想要的元素数量的函数,而不是步长(step)。

linspace 定义如下:

  1. numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)[source

举例:

  1. from numpy import pi
  2. np.linspace(0, 2, 9) # 从0到2生成9个数
  3. # 输出: array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])

又比如:

  1. x = np.linspace( 0, 2*pi, 100 )
  2. np.sin(x)

创建随机数组

通过以下方式生成的随机数, 每次运行结果都不一样:

  1. np.random.random([3,3]) # 数组为一个3*3的矩阵

使用 np.random.randn 生成随机数组,随机数取值范围在[0, 1)之间。

  1. np.random.randn(2,3) # 数组为一个2*3的矩阵

以上方式,创建的是浮点数,可以通过 floor 或 ceil 函数为生成的随机数组取整:

  1. np.floor(10*np.random.random((3,4)))
  2. np.ceil(10*np.random.random((3,4)))

使用随机数种子生成随机数组

使用种子生成ndarray, 实际上并不是真正的随机数, 通常我们可以用当前系统时间作为种子。以下代码, 无论运行多少次结果都一样。

  1. np.random.seed(123)

随机打乱数据

通过 np.random.shuffle 可以将已有的数组顺序随机打乱。

  1. nd5=np.random.random([3,3]) # 数组为一个3*3的矩阵
  2. np.random.shuffle(nd5)

均匀分布

使用 np.random.uniform 生成均匀分布随机数,可以指定随机数取值范围和数组形状。

  1. np.random.uniform(low = -1.0, high = 1.0, size=(2,2)) # 生成一个2*2的数组,取值范围[-1,1)

正态分布

使用 np.random.normal 生成正态分布随机数,指定均值loc和方差scale。

  1. np.random.normal(loc = 1.0, scale = 1.0, size = (3,3))

随机选取元素

使用 np.random.choice 可以随机选取元素,使用size指定选取元素的数量。

  1. a = np.arange(30)
  2. b = np.random.choice(a, size=5)

ndarray的属性

ndarray对象更重要的属性有:

  • ndarray.ndim - 数组的轴(维度)的个数。在Python世界中,维度的数量被称为rank。
  • ndarray.shape - 数组的维度。这是一个整数的元组,表示每个维度中数组的大小。对于有 n 行和 m 列的矩阵,shape 将是 (n,m)。因此,shape 元组的长度就是rank或维度的个数 ndim
  • ndarray.size - 数组元素的总数。这等于 shape 的元素的乘积。
  • ndarray.dtype - 一个描述数组中元素类型的对象。可以使用标准的Python类型创建或指定dtype。另外NumPy提供它自己的类型。例如numpy.int32、numpy.int16和numpy.float64。
  • ndarray.itemsize - 数组中每个元素的字节大小。例如,元素为 float64 类型的数组的 itemsize 为8(=64/8),而 complex32 类型的数组的 itemsize 为4(=32/8)。它等于 ndarray.dtype.itemsize

示例:

  1. array = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
  2. print(array)
  3. #数组维度
  4. print(array.ndim)
  5. #数组形状
  6. print(array.shape)
  7. #数组元素个数
  8. print(array.size)
  9. #数组元素类型
  10. print(array.dtype)
  11. #数组中每个元素的字节大小
  12. print(array.itemsize)
  1. [[ 1 2 3]
  2. [ 4 5 6]
  3. [ 7 8 9]
  4. [10 11 12]]
  5. 2
  6. (4, 3)
  7. 12
  8. int32
  9. 4

**

ndarray数据类型(dtype)

**
NumPy支持比Python更多种类的数字类型。支持的原始类型与 C 中的原始类型紧密相关:

Numpy 的类型 C 的类型 描述
np.bool bool 存储为字节的布尔值(True或False)
np.byte signed char 平台定义
np.ubyte unsigned char 平台定义
np.short short 平台定义
np.ushort unsigned short 平台定义
np.intc int 平台定义
np.uintc unsigned int 平台定义
np.int_ long 平台定义
np.uint unsigned long 平台定义
np.longlong long long 平台定义
np.ulonglong unsigned long long 平台定义
np.half / np.float16 半精度浮点数:符号位,5位指数,10位尾数
np.single float 平台定义的单精度浮点数:通常为符号位,8位指数,23位尾数
np.double double 平台定义的双精度浮点数:通常为符号位,11位指数,52位尾数。
np.longdouble long double 平台定义的扩展精度浮点数
np.csingle float complex 复数,由两个单精度浮点数(实部和虚部)表示
np.cdouble double complex 复数,由两个双精度浮点数(实部和虚部)表示。
np.clongdouble long double complex 复数,由两个扩展精度浮点数(实部和虚部)表示。

由于其中许多都具有依赖于平台的定义,因此提供了一组固定大小的别名:

Numpy 的类型 C 的类型 描述
np.int8 int8_t 字节(-128到127)
np.int16 int16_t 整数(-32768至32767)
np.int32 int32_t 整数(-2147483648至2147483647)
np.int64 int64_t 整数(-9223372036854775808至9223372036854775807)
np.uint8 uint8_t 无符号整数(0到255)
np.uint16 uint16_t 无符号整数(0到65535)
np.uint32 uint32_t 无符号整数(0到4294967295)
np.uint64 uint64_t 无符号整数(0到18446744073709551615)
np.intp intptr_t 用于索引的整数,通常与索引相同 ssize_t
np.uintp uintptr_t 整数大到足以容纳指针
np.float32 float
np.float64 / np.float_ double 请注意,这与内置python float的精度相匹配。
np.complex64 float complex 复数,由两个32位浮点数(实数和虚数组件)表示
np.complex128 / np.complex_ double complex 请注意,这与内置python 复合体的精度相匹配。


修改数组数据类型

通过 astype 可以修改数组的类型:

  1. a = np.array([1,2,3])
  2. b = a.astype(np.float64)
  3. print(b)

输出:

  1. [1. 2. 3.]

改变数组的形状

reshape

通过reshape可以重新定义数组的形状。通过此方法将产生一个新数组,不会改变原数组的形状。

  1. a = np.arange(16)
  2. b = a.reshape(4,4)
  3. print(a)
  4. print(b)
  1. array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
  2. array([[ 0, 1, 2, 3],
  3. [ 4, 5, 6, 7],
  4. [ 8, 9, 10, 11],
  5. [12, 13, 14, 15]])

注意:数组元素个总数前后得一致,即变换前后得size保持不变
**

resize

通过 resize 调整数组形状, 通过此方法改变的形状作用于原数组, 而不会产生一个新的数组

  1. a=np.arange(16).reshape(4,4)
  2. a.resize((2,8))

或者直接修改数组的 shape 值:

  1. a=np.arange(16)
  2. a.shape=(4,4)

**

往ndarray中添加元素**

有两种方式可以往ndarray中添加元素

  • np.concatenate,先将要添加的元素变成list形式与目标数组进行拼接,注意输入为一个tuple
  • np.append,直接向目标数组中添加元素

**

  1. losses = np.array([])
  2. losses = np.concatenate((losses, [1]))
  3. losses = np.append(losses, 2)
  4. losses = np.append(losses, np.array([3]))
  5. print(losses) # [1. 2. 3.]

注意,一定不要忘记用赋值覆盖原数组,否则原数组将不会变
**

展平数组

使用 ravel 可以展平数组:

  1. # 展开二维数组
  2. a=np.arange(16).reshape([4,4])
  3. a.ravel() # array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
  4. # 展开多维数组
  5. a=np.arange(27).reshape([3,3,3])
  6. a.ravel()

ravel 默认是行优先展开, 如果要列优先展开, 可以带上 'F' 参数:

  1. a.ravel('F')

通过flatten可以将数组全部展平:

  1. a.flatten()

堆叠数组

几个数组可以通过 vstack 或 hstack 沿不同的轴堆叠在一起

  1. a=np.array([1,2,3,4])
  2. b=np.array([5,6,7,8])

按垂直方向堆叠

  1. np.vstack([a,b])

结果:

  1. array([[1, 2, 3, 4],
  2. [5, 6, 7, 8]])

按水平方向堆叠

  1. np.hstack([a,b])

结果:

  1. array([1, 2, 3, 4, 5, 6, 7, 8])

合并数组

使用 append 可以合并两个数组, 指定 axis=0 按行合并:

  1. np.append(a, b, axis=0)

结果:

  1. array([1, 2, 3, 4, 5, 6, 7, 8])

拆分数组

数组可以通过 vsplit 或 hsplit 沿不同的轴堆叠在一起

  1. a=np.arange(16).reshape(4,4)

按垂直方向拆分

  1. np.vsplit(a,2)

结果:

  1. [array([[0, 1, 2, 3],
  2. [4, 5, 6, 7]]),
  3. array([[ 8, 9, 10, 11],
  4. [12, 13, 14, 15]])]

按水平方向拆分

  1. np.hsplit(a,2)

结果:

  1. [array([[ 0, 1],
  2. [ 4, 5],
  3. [ 8, 9],
  4. [12, 13]]),
  5. array([[ 2, 3],
  6. [ 6, 7],
  7. [10, 11],
  8. [14, 15]])]