Numpy(二)快速开始


基础

1 基本概念

同质多维数组的轴

NumPy 的主要对象是「同质的多维数组(homogeneous multidimensional array)」。它是一个元素(通常是数字)的表格,所有元素类型相同,由「非负整数」的「元组索引」。在 NumPy 中,「维度」被称为「轴(axes)」。

3D坐标

同质多维数组的轴

3D空间中一个点的坐标[1,2,1]的数组有一个轴。该轴有3个元素,所以它的长度为3。

二轴数组

同质多维数组的轴

该数组有2个轴。第一个轴的长度为2,第二个轴的长度为3。

[[1., 0., 0.],
 [0., 1., 2.]]

ndarray

NumPy的数组类称为ndarray。也成为array。注意numpy. array与标准Python编程语言库类array.array不同,后者只处理一维数组,提供的功能较少。

ndarray属性

  1. ndarray.ndim
    数组的轴数(维度数)

  2. ndarray.shape
    数组的维度。这是一个「整数元组」,指示每个维度中数组的大小。对于具有 n 行和 m 列的矩阵,shape 将是 (n,m)。因此,shape 元组的长度就是「轴数」,即 ndim。

  3. ndarray.size
    数组中元素的总数。这等于 shape 中元素的乘积。

  4. ndarray.dtype
    描述数组中元素类型的一个对象。可以使用标准的 Python 类型创建或指定 dtype。此外,NumPy 还提供了自己的类型。numpy.int32、numpy.int16 和 numpy.float64 是一些示例。

  5. ndarray.itemsize
    数组中每个元素的大小(以字节为单位)。

  6. ndarray.data
    包含数组「实际元素」的缓冲区。通常不需要使用这个属性,因为会使用索引功能来访问数组中的元素。

各属性代码

ndarray属性

import numpy as np
a = np.arange(15).reshape(3, 5)#创建一个3*5的数组
print(a)#打印数组
'''
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
'''
print(a.shape)#打印数组的形状
'''
(3, 5)
'''
print(a.ndim)#打印数组的维度
'''
2
'''
print(a.dtype.name)#打印数组的数据类型
'''
int32
'''
print(a.itemsize)#打印数组中每个元素的大小
'''
4
'''
print(a.size)#打印数组中元素的个数
'''
15
'''
print(type(a))#打印数组的类型
'''
<class 'numpy.ndarray'>
'''

b = np.array([6, 7, 8])#创建一个数组
print(b)#打印数组
'''
[6 7 8]
'''
print(type(b))#打印数组的类型
'''
<class 'numpy.ndarray'>
'''

2 创建数组

python列表创建

  1. 可以使用「数组函数」从常规Python编程语言「列表」或「元组」创建array。生成数组的类型是从序列中元素的类型推断出来的。
  2. 注意:array()的参数要使用准确。
  3. array将「序列序列」转换为二维数组,将「序列序列转」换为三维数组,依此类推。
  4. 数组的类型也可以在创建时显式指定。

列表创建代码

python列表创建

# 1 列表创建一维数组
a = np.array([2, 3, 4])
'''
[2 3 4]
'''
# 2
# b = np.array(1,2,3)#错误的创建方式
'''
TypeError: array() takes from 1 to 2 positional arguments but 3 were given
'''

# 3 列表元组组合创建二维数组
b = np.array([(1, 2, 3),(4.1, 4.2, 4.3)])#创建一个二维数组
print(b)#打印数组
print(b.dtype.name)#打印数组的数据类型
'''
[[1.  2.  3. ]
 [4.1 4.2 4.3]]
'''

初始占位符

通常,数组的元素最初是未知的,但其大小是已知的。因此,NumPy 提供了几个函数来创建具有初始占位符内容的数组。这些函数最大限度地减少了增长数组的需要,这是一个代价高昂的操作。

五种初始占位符

初始占位符

#初始占位符
#1 zeros
print(np.zeros((3, 4)))#创建一个3*4的全0数组
'''
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
'''
#2 ones
print(np.ones((2, 3, 4), dtype=np.int16))#创建一个2*3*4的全1数组
'''
[[[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]

 [[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]]
'''
#3 empty
print(np.empty((2, 3)))#创建一个2*3的空数组
#empty创建一个数组,其初始内容是随机的,取决于内存的状态。
'''
[[1.39069238e-309 1.39069238e-309 1.39069238e-309]
 [1.39069238e-309 1.39069238e-309 1.39069238e-309]]
'''
#4 arange
print(np.arange(10, 30, 5))#创建一个10到30,步长为5的数组
print(np.arange(0, 2, 0.3))#创建一个0到2,步长为0.3的数组
'''
[10 15 20 25]
[0.  0.3 0.6 0.9 1.2 1.5 1.8]
'''

#5 linspace
'''
当 arange 函数使用浮点数参数时,由于有限的浮点数精度,通常无法预测获得的元素数量。
因此,通常最好使用 linspace 函数,该函数接受我们想要的元素数量作为参数,而不是步长
'''
from numpy import pi
print(np.linspace(0, 2, 9))#创建一个0到2,元素个数为9的数组
'''
[0.   0.25 0.5  0.75 1.   1.25 1.5  1.75 2.  ]
'''
x = np.linspace(0, 2*pi, 10)#创建一个0到2*pi,元素个数为10的数组
f = np.sin(x)#对数组中的每个元素求正弦值
print(x)
'''
[0.         0.6981317  1.3962634  2.0943951  2.7925268  3.4906585
 4.1887902  4.88692191 5.58505361 6.28318531]
'''
print(f)
'''
[ 0.00000000e+00  6.42787610e-01  9.84807753e-01  8.66025404e-01
  3.42020143e-01 -3.42020143e-01 -8.66025404e-01 -9.84807753e-01
 -6.42787610e-01 -2.44929360e-16]
'''

3 打印数组

数组打印

当打印一个数组时,NumPy 以类似于嵌套列表的方式显示它,但布局如下:

  1. 最后一个轴从左到右打印,
  2. 倒数第二个轴从上到下打印,
  3. 其余的也是从上到下打印,每个切片之间用一个空行分隔。
  4. 如果数组太大而无法打印,NumPy会自动跳过数组的中心部分,只打印角落。
  5. 要禁用第四点并强制NumPy打印整个数组,可以使用set_printoptions更改打印选项。

一维数组被打印成行,二维数组被打印成矩阵,三维数组被打印成矩阵列表。

对应的代码例子

数组打印

#一维数组
print(np.arange(6))#创建一个0到5的数组
'''
[0 1 2 3 4 5]
'''
#二维数组
print(np.arange(12).reshape(4, 3))#创建一个4*3的数组
'''
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
'''
#三维数组
print(np.arange(24).reshape(2, 3, 4))#创建一个2*3*4的数组
'''
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
'''
#省略打印
print(np.arange(10000))
'''
[   0    1    2 ... 9997 9998 9999]
'''
print(np.arange(10000).reshape(100, 100))
'''
[[   0    1    2 ...   97   98   99]
 [ 100  101  102 ...  197  198  199]
 [ 200  201  202 ...  297  298  299]
 ...
 [9700 9701 9702 ... 9797 9798 9799]
 [9800 9801 9802 ... 9897 9898 9899]
 [9900 9901 9902 ... 9997 9998 9999]]
'''
#强制打印
# np.set_printoptions(threshold=np.nan)#设置打印选项

4 基础操作

元素应用

「数组」上的算术运算符按「元素应用」。创建一个新数组并用结果填充。

一般操作

元素应用

a = np.array([20, 30, 40, 50])#创建一个数组
b = np.arange(4)#创建一个数组

#1.减法
print(b)
print(a-b)
'''
[0 1 2 3]
[20 29 38 47]
'''
#2.平方
print(b**2)
'''
[0 1 4 9]
'''
#3.三角函数
print(10*np.sin(a))#对数组中的每个元素求正弦值
'''
[ 9.12945251 -9.88031624  7.4511316  -2.62374854]
'''
#4.判断数组中元素是否大于35
print(a<35)#返回一个布尔数组
'''
[ True  True False False]
''' 

矩阵与Numpy的乘积

与许多「矩阵语言」不同,乘积运算符*在NumPy数组中按元素操作。「矩阵乘积」可以使用「@运算符」(在python>=3.5中)或「dot点函数」执行:

乘积例子

矩阵与Numpy的乘积

A = np.array([[1,1],
              [0,1]])#创建一个2*2的数组
B = np.array([[2,0],
              [3,4]])#创建一个2*2的数组
print(A*B)#数组对应元素相乘
'''
[[2 0]
 [0 4]]
'''
print(A@B)#矩阵乘法
'''
[[5 4]
 [3 4]]
'''
print(A.dot(B))#矩阵乘法
'''
[[5 4]
 [3 4]]
'''

精确性

当对「不同类型」的数组进行操作时,生成的数组的类型对应于更通用或「更精确」的类型(一种称为「向上转换」的行为)。

精确度的例子

精确性

from numpy import pi
a = np.ones(3, dtype=np.int32)#创建一个全1的数组
b = np.linspace(0, pi, 3)#创建一个0到pi的数组
print(a)
print(b)
print(b.dtype.name)#打印数组的数据类型
'''
float64
'''
c = a+b#数组相加
print(c)#打印数组
'''
[1.         2.57079633 4.14159265]
'''
d = np.exp(c*1j)#对数组中的每个元素求指数值
print(d)#打印数组
'''
[ 0.54030231+0.84147098j -0.84147098+0.54030231j -0.54030231-0.84147098j]
'''
print(d.dtype.name)#打印数组的数据类型
'''
complex128
'''

轴向计算

默认情况下,这些操作适用于数组,就好像它是一个数字列表,而不管它的形状如何。但是,通过指定「轴参数」,可以沿着数组的指定轴应用操作

行和列和与累加

轴向计算

b = np.arange(12).reshape(3, 4)#创建一个3*4的数组
print(b)#打印数组
'''
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
'''
print(b.sum(axis=0))#对每一列求和
'''
[12 15 18 21]
'''
print(b.min(axis=1))#对每一行求最小值
'''
[0 4 8]
'''
print(b.cumsum(axis=1))#对每一行元素进行累加
'''
[[ 0  1  3  6]
 [ 4  9 15 22]
 [ 8 17 27 38]]
'''

5 索引,切片,迭代

一维数组

一维数组可以进行索引、切片和迭代操作,与Python中的列表list和其他序列类型非常相似。

对应例子

一维数组

a = np.arange(10)**3#创建一个0到9的数组,每个元素的立方
print(a)#打印数组
'''
[  0   1   8  27  64 125 216 343 512 729]
'''
print(a[2])#索引
'''
8
'''
print(a[2:5])#切片
'''
[ 8 27 64]
'''
# a[:6:2] = -1000#等价于a[0:6:2] = -1000
a[::1] += 1
print(a)#打印数组
'''
[  1   2   9  28  65 126 217 344 513 730]
'''
for i in a:#迭代
    print(i-1)

多维数组

多维数组可以在每个轴上有一个索引。这些索引以逗号分隔的形式在一个「元组」中给出。

索引不足切片补全

在多维数组或数据结构中,当提供的「索引(index)」数量少于「数组的维度(axes)」数量时,那些没有明确指定索引的维度将被视为完整的切片(slice)。换句话说,如果一个数组有多个维度,而在访问数组时只提供了部分维度的索引,那么未提供索引的维度会被当作包含了该维度上所有元素的切片。

二位数组例子

多维数组

def f(x, y):
    return 10*x+y
b = np.fromfunction(f, (5, 4), dtype=int)#创建一个5*4的数组
'''
f 是一个接受两个参数的函数(因为数组是二维的),
这些参数分别代表数组的行索引和列索引。fromfunction 会生成两个坐标数组,
一个表示行索引,另一个表示列索引,然后将这些数组传递给函数 f。

参数 dtype=int 指定了生成的数组的数据类型为整数。
如果没有指定 dtype,默认的数据类型是浮点数
'''
print(b)#打印数组
'''
[[ 0  1  2  3]
 [10 11 12 13]
 [20 21 22 23]
 [30 31 32 33]
 [40 41 42 43]]
'''
print(b[2, 3])#索引
'''
23
'''
print(b[0:5, 1])#切片,获取第2列
'''
[ 1 11 21 31 41]
'''
print(b[:, 1])#获取第2列
'''
[ 1 11 21 31 41]
'''
print(b[1:3, :])#获取第2-3行
'''
[[10 11 12 13]
 [20 21 22 23]]
'''
print(b[1:3,1:3])#获取第2-3行,第2-3列
'''
[[11 12]
 [21 22]]
'''
print(b[-1])#获取最后一行
'''
[40 41 42 43]
'''
for row in b:
    print(row)#迭代
'''
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]
'''

for element in b.flat:#迭代,逐个元素迭代
    print(element)
'''
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33
40
41
42
43
'''

形状操作

1 改变数组形状


文章作者: Hkini
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hkini !
评论
  目录