栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

NumPy基础(一)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

NumPy基础(一)

NumPy基础(一)
  • NumPy基础概念与属性
  • 创建NumPy.ndarray数组(Array Creation)
  • 打印数组(Printing Arrays)
  • 基础运算(Basic Operations)
  • 通用函数(Universal Functions)
  • 索引,切片和迭代(Indexing, Slicing and Iterating)

NumPy基础概念与属性

NumPy’s main object is the homogeneous multidimensional array. It is a table of elements (usually numbers), all of the same type, indexed by a tuple of non-negative integers. In NumPy dimensions are called axes.

NumPy的主要数据对象或者说数据实例是多维数组(ndarray),可以理解成由具有同等数据类型的元素所构成的一张表,通常是由实数组成,也可以是其他的python数据体。在NumPy中数组的维度(dimensions)被称为轴(axes),可以理解成笛卡尔坐标系中的x轴,y轴,z轴的那个轴。

For example, the array for the coordinates of a point in 3D space, [1, 2, 1], has one axis. That axis has 3 elements in it, so we say it has a length of 3. In the example pictured below, the array has 2 axes. The first axis has a length of 2, the second axis has a length of 3.

例如,3D空间中某个点的坐标由数组[1, 2, 1]表示,具有1个axis,这个axis含有3个元素,长度为3。又如下方数组所示,其具有2个axis,第一个axis的长度为2,第二个axis的长度为3。

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

NumPy’s array class is called ndarray. It is also known by the alias array. Note that numpy.array is not the same as the Standard Python Library class array.array, which only handles one-dimensional arrays and offers less functionality. The more important attributes of an ndarray object are:

NumPy的数组类称为ndarray,别名是array。值得注意的是,numpy.array和标准Python库(Standard Python Library)中的数组类array.array并不相同,后者只能处理1D数组且提供很少的功能函数。ndarray对象更重要的属性是:

  • ndarray.ndim
    the number of axes (dimensions) of the array.
    数组的轴(维度)数量。

  • ndarray.shape
    the dimensions of the array. This is a tuple of integers indicating the size of the array in each dimension. For a matrix with n rows and m columns, shape will be (n,m). The length of the shape tuple is therefore the number of axes, ndim.
    数组的维度,由整数构成的元组表示,表明数组每一维的尺寸。一个n行m列矩阵的shape就是(n, m)。因此shape元组的长度就是轴的数量,即ndim。

  • ndarray.size
    the total number of elements of the array. This is equal to the product of the elements of shape.
    数组中所有元素的总数,等于数组的shape中各个维度值的乘积。

  • ndarray.dtype
    an object describing the type of the elements in the array. One can create or specify dtype’s using standard Python types. Additionally NumPy provides types of its own. numpy.int32, numpy.int16, and numpy.float64 are some examples.
    描述数组中的元素数据类型,可以使用标准python类型来创建或者指定数组的数据类型。另外,NumPy也提供自有的一些数据类型,例如:numpy.in32,numpy.int16,numpy.float64等。

  • ndarray.itemsize
    the size in bytes of each element of the array. For example, an array of elements of type float64 has itemsize 8 (=64/8), while one of type complex32 has itemsize 4 (=32/8). It is equivalent to ndarray.dtype.itemsize.
    数组中每个元素在内存中占用的字节数。例如,数据类型为float64的数组的itemsize为8(=64/8),数据类型为complex32的数组的itemsize为4(=32/8)。等同于ndarray.dtype.itemsize。

  • ndarray.data
    the buffer containing the actual elements of the array. Normally, we won’t need to use this attribute because we will access the elements in an array using indexing facilities.
    存储数组真正元素的缓存区。通常,我们用不到这个属性,因为可以通过数组索引的形式来访问数组中的元素。

>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> type(a)

>>> a.ndim
2
>>> a.shape
(3, 5)
>>> a.size
15
>>> a.dtype
dtype('int32')
>>> a.dtype.name
'int32'
>>> a.itemsize
4
创建NumPy.ndarray数组(Array Creation)

There are several ways to create arrays.
For example, you can create an array from a regular Python list or tuple using the array function. The type of the resulting array is deduced from the type of the elements in the sequences.

创建mumpy.ndarray数组的方式有多种。
例如,你可以使用Numpy.array()或者Numpy.asarray()函数将一个Python中的list或者tuple数据转成ndarray数组,数组的数据类型根据来源序列数据的类型进行推导。

>>> import numpy as np
>>> a = np.array([1, 2, 3, 4])
>>> a
array([1, 2, 3, 4])
>>> a.dtype
dtype('int32')
>>> b = np.array([1.1, 2.2, 3.4])
>>> b.dtype
dtype('float64')
>>> c = np.asarray([1, 2, 3, 4])
>>> c.dtype
dtype('int32')

numpy.array()和numpy.asarray()的实现功能都是一样的,将一个序列数据转成numpy.ndarray数组,但是有一点点的区别是,前者无论来源数据是不是NumPy数组,都会创建一个新的数组,而后者仅仅在非Numpy数组的情形下生成新的数组,这样在实际使用时会节省内存,但还是要根据具体场景决定采用哪个函数,避免错误使用带来错误。

x = [1, 2, 3, 4]
a = np.asarray(x)  # 创建新的数组
b = np.array(x)  # 创建新的数组
id(x)  # 1986881306560
id(a)  # 1986881373936
id(b)  # 1986881373840
c = np.asarray(a)
d = np.array(a)
id(c)  # 1986881373936
id(d)  # 1986740290928

id(c) == id(a)  # True
id(d) == id(a)  # False

A frequent error consists in calling array with multiple arguments, rather than providing a single sequence as an argument.

调用numpy.array()的常见错误在于多个数值作为参数进行传递,而非一个完整的序列作为参数。
理应是传入一个list或者tuple数据。

>>> import numpy as np
>>> a = np.array(1, 2, 3, 4)   # Wrong
Traceback (most recent call last):
  File "", line 1, in 
TypeError: array() takes from 1 to 2 positional arguments but 4 were given
>>> a = np.array([1, 2, 3, 4])  # Right
>>> b = np.array(((1, 3, 5, 7), (2, 4, 6, 8)))  # Right

The type of the array can also be explicitly specified at creation time:

可以在创建数组时显式的指定数据类型。

>>> c = np.array([[1, 2], [3, 4]], dtype=complex)
>>> c
array([[1.+0.j, 2.+0.j],
       [3.+0.j, 4.+0.j]])
>>> d = np.array([[1, 2], [3, 4]], dtype=np.float32)
>>> d
array([[1., 2.],
       [3., 4.]], dtype=float32)

Often, the elements of an array are originally unknown, but its size is known. Hence, NumPy offers several functions to create arrays with initial placeholder content. These minimize the necessity of growing arrays, an expensive operation.
The function zeros creates an array full of zeros, the function ones creates an array full of ones, and the function empty creates an array whose initial content is random and depends on the state of the memory. By default, the dtype of the created array is float64, but it can be specified via the key word argument dtype.

有时,数组中各元素的具体值最初是未知的,但是尺寸或者说形状是已知的。因此,NumPy提供了一些函数来创建含有初始内容占位符的数组。这些函数减少了随着数据增多数组逐渐增大的必要性,因为NumPy数组一旦创建,是无法改变尺寸的,只能不断创建新的数组来满足数据的存放,这是一个代价很高的操作,在C语言中需要重新分配一块内存,将老的数组里的数据复制到新的数组中,在将新的数据加进去,然后释放掉老数组的内存,重复此操作,直至数据完全满足需求。
numpy.zeros()和numpy.ones()函数可以预先创建一个数值全0或全1的预先指定尺寸的数组,numpy.empty()则创建一个空数组,其值是当前内存块中已存在的数值。创建的数组默认数据类型是numpy.float64,但是可以通过关键词参数dtype指定数据类型。

>>> a = np.zeros((2, 5))
>>> a
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
>>> a.dtype
dtype('float64')
>>> b = np.ones((3, 4), dtype=np.float32)
>>> b
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]], dtype=float32)
>>> b.dtype
dtype('float32')
>>> c = np.empty((3, 4), dtype=np.float32)
>>> c
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]], dtype=float32)
>>> c.dtype
dtype('float32')

To create sequences of numbers, NumPy provides the arange function which is analogous to the Python built-in range, but returns an array.

为了创建序列化数值数组,NumPy提供了numpy.arrange()函数,和Python的内置函数range()很像,但是返回的是一个数组。

>>> np.arange(1, 5, 1)
array([1, 2, 3, 4])
>>> np.arange(1, 5, 0.5)
array([1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])

When arange is used with floating point arguments, it is generally not possible to predict the number of elements obtained, due to the finite floating point precision. For this reason, it is usually better to use the function linspace that receives as an argument the number of elements that we want, instead of the step:

当numpy.arange()使用浮点类型的参数时,由于有限的浮点数精度,它通常不能预测创建的数组的长度。出于这个原因,通常更好的方式是使用函数numpy.linspace(),传递一个我们想要的数组长度作为参数,而不是像numpy.arange()那样采用步长的方式。

>>> np.arange(0, 2, 0.25)
array([0.  , 0.25, 0.5 , 0.75, 1.  , 1.25, 1.5 , 1.75])
>>> np.linspace(0, 2, 9)
array([0.  , 0.25, 0.5 , 0.75, 1.  , 1.25, 1.5 , 1.75, 2.  ])
打印数组(Printing Arrays)

When you print an array, NumPy displays it in a similar way to nested lists, but with the following layout:

  • the last axis is printed from left to right,
  • the second-to-last is printed from top to bottom,
  • the rest are also printed from top to bottom, with each slice separated from the next by an empty line.

One-dimensional arrays are then printed as rows, bidimensionals as matrices and tridimensionals as lists of matrices.

打印数组时,NumPy和嵌套list的打印方式类似,但是遵从以下布局规则:

  • 最后一维的数据打印是从左至右
  • 从第二维到最后一维的打印是从上至下
  • 其余的也都是从上至下打印,切片间使用空白行间隔开。
    一维数组作为行向量进行打印,二维数组作为矩阵,三维数组作为二维数组的list。
>>> a = np.arange(5)  # 1D array
>>> print(a)
[0 1 2 3 4]
>>> a = np.arange(10).reshape(2, 5)  # 2D array
>>> print(a)
[[0 1 2 3 4]
 [5 6 7 8 9]]
>>> a = np.arange(24).reshape(2, 3, 4)  # 3D array
>>> print(a)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

If an array is too large to be printed, NumPy automatically skips the central part of the array and only prints the corners:

如果打印一个非常大的数组,NumPy会自动跳过数组的中间部分而只打印四个角点。

>>> print(np.arange(100000))
[    0     1     2 ... 99997 99998 99999]
>>> print(np.arange(100000).reshape(100, 1000))
[[    0     1     2 ...   997   998   999]
 [ 1000  1001  1002 ...  1997  1998  1999]
 [ 2000  2001  2002 ...  2997  2998  2999]
 ...
 [97000 97001 97002 ... 97997 97998 97999]
 [98000 98001 98002 ... 98997 98998 98999]
 [99000 99001 99002 ... 99997 99998 99999]]
>>>

To disable this behaviour and force NumPy to print the entire array, you can change the printing options using set_printoptions.

为了禁用这种行为并强制NumPy打印整个数组,可以使用numpy.set_printoptions()来改变打印设置。

>>> import numpy as sys
>>> import numpy as np
>>> np.set_printoptions(threshold=sys.maxsize)  # sys module should be imported
# 或者可以使用np.inf
>>> np.set_printoptions(threshold=np.inf)
>>> 
基础运算(Basic Operations)

Arithmetic operators on arrays apply elementwise. A new array is created and filled with the result.

数组的算术运算是元素与元素之间的运算。创建一个新的数组,并将对应的结果填进去。

>>> a = np.array([20, 30, 40, 50])
>>> b = np.arange(4)
>>> b
array([0, 1, 2, 3])
>>> c = a - b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10 * np.sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a < 35
array([ True,  True, False, False])

Unlike in many matrix languages, the product operator * operates elementwise in NumPy arrays. The matrix product can be performed using the @ operator (in python >=3.5) or the dot function or method:

和许多矩阵语言不同,在NumPy数组中乘积运算符*是元素与元素之间的操作符。矩阵的乘积可以通过@运算符(需要python>=3.5)或者numpy.dot()函数来实现。

>>> A = np.array([[1, 1], [0, 1]])
>>> A
array([[1, 1],
       [0, 1]])
>>> B = np.array([[2, 0], [3, 4]])
>>> B
array([[2, 0],
       [3, 4]])
>>> A*B
array([[2, 0],
       [0, 4]])
>>> A@B
array([[5, 4],
       [3, 4]])
>>> A.dot(B)
array([[5, 4],
       [3, 4]])
>>> np.dot(A, B)
array([[5, 4],
       [3, 4]])
>>>

Some operations, such as += and *=, act in place to modify an existing array rather than create a new one.

一些运算,例如+=和*=,将运算结果就地保存到一个已存在的数组而不是创建一个新的数组。

>>> a = np.arange(6).reshape(2, 3)
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
>>> b = np.random.rand(2, 3)
>>> b
array([[0.45280362, 0.1485653 , 0.46287907],
       [0.09961483, 0.75078263, 0.98617924]])
>>> b += a
>>> b
array([[2.45280362, 2.1485653 , 2.46287907],
       [2.09961483, 2.75078263, 2.98617924]])
>>> a+=b
Traceback (most recent call last):
  File "", line 1, in 
numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('float64') to dtype('int32') with casting rule 'same_kind'

When operating with arrays of different types, the type of the resulting array corresponds to the more general or precise one (a behavior known as upcasting).

当参与运算的两个数组具有不同的数据类型时,运算结果的数据类型对应其中更通用或者精度更高的数据类型(这种行为被称作向上类型转换)。

Many unary operations, such as computing the sum of all the elements in the array, are implemented as methods of the ndarray class.

更多元运算,例如计算数组所有元素之和,已经作为类numpy.ndarray的方法实现了。

>>> a = np.random.rand(2, 3)
>>> a
array([[0.08643897, 0.95522   , 0.60983787],
       [0.693373  , 0.27511741, 0.53285288]])
>>> a.sum()
3.152840122837532
>>> a.min()
0.08643896508876026
>>> a.max()
0.9552200009488596

By default, these operations apply to the array as though it were a list of numbers, regardless of its shape. However, by specifying the axis parameter you can apply an operation along the specified axis of an array:

通常,这些运算运行时把数组当作一个含有所有数值的list,忽略了数组的形状。不过,可以通过指定axis参数,将运算作用于特定的维度。

>>> a
array([[0.08643897, 0.95522   , 0.60983787],
       [0.693373  , 0.27511741, 0.53285288]])
>>> a.sum(axis=0)
array([0.77981196, 1.23033741, 1.14269075])
>>> a.sum(axis=1)
array([1.65149684, 1.50134329])
>>> a.min(axis=0)
array([0.08643897, 0.27511741, 0.53285288])
>>> a.min(axis=1)
array([0.08643897, 0.27511741])
>>> a.max(axis=0)
array([0.693373  , 0.95522   , 0.60983787])
>>> a.max(axis=1)
array([0.95522 , 0.693373])
通用函数(Universal Functions)

NumPy provides familiar mathematical functions such as sin, cos, and exp. In NumPy, these are called “universal functions” (ufunc). Within NumPy, these functions operate elementwise on an array, producing an array as output.

NumPy提供类似的数学函数,例如numpy.sin(),numpy.cos(),和numpy.exp()。这些在NumPy中被称为“通用函数”(ufunc)。这些函数依然是元素级的操作作用于数组上,输入一个数组,输出一个于输入具有相同形状的数组。

>>> B = np.arange(3)
>>> B
array([0, 1, 2])
>>> np.exp(B)
array([1.        , 2.71828183, 7.3890561 ])
>>> np.sqrt(B)
array([0.        , 1.        , 1.41421356])
>>> C = np.array([2., -1., 4.])
>>> np.add(B, C)
array([2., 0., 6.])
索引,切片和迭代(Indexing, Slicing and Iterating)

One-dimensional arrays can be indexed, sliced and iterated over, much like lists and other Python sequences.

一维数组的索引,切片和迭代和Python中的list或者其他序列类型很像。

>>> a = np.arange(10)**3
>>> a
array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> # equivalent to a[0:6:2] = 1000;
>>> # from start to position 6, exclusive, set every 2nd element to 1000
>>> a[:6:2] = 1000
>>> a
array([1000,    1, 1000,   27, 1000,  125,  216,  343,  512,  729])
>>> a[::-1]  # reversed a
array([ 729,  512,  343,  216,  125, 1000,   27, 1000,    1, 1000])
>>> for i in a:
...    print(i**(1 / 3.))
...
9.999999999999998
1.0
9.999999999999998
3.0
9.999999999999998
4.999999999999999
5.999999999999999
6.999999999999999
7.999999999999999
8.999999999999998

Multidimensional arrays can have one index per axis. These indices are given in a tuple separated by commas:

多维数组每一维有一个索引。这些索引使用逗号隔开组成一个元组。

>>> a = np.arange(12).reshape(4, 3)
>>> a
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])
>>> a[1, 2]
5
>>> a[:, 0:2]
array([[ 0,  1],
       [ 3,  4],
       [ 6,  7],
       [ 9, 10]])
>>> a[1:3, :]
array([[3, 4, 5],
       [6, 7, 8]])
>>> a[1:3, 0]
array([3, 6])

When fewer indices are provided than the number of axes, the missing indices are considered complete slices:

当提供的索引长度小于数组的维度时,缺少的索引被认为是整个切片,即其维度的长度。

>>> b = np.arange(12).reshape(4, 3)
>>> b
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])

>>> b[0]   # 等同于b[0, :]
array([0, 1, 2])

The expression within brackets in b[i] is treated as an i followed by as many instances of : as needed to represent the remaining axes. NumPy also allows you to write this using dots as b[i, …].

b[i]中[i]部分会当作i后面跟了很多冒号:用来表示其余的维度。NumPy也允许使用...来表示其余的维度。

The dots (…) represent as many colons as needed to produce a complete indexing tuple. For example, if x is an array with 5 axes, then

  • x[1, 2, ...] is equivalent to x[1, 2, :, :, :],
  • x[..., 3] to x[:, :, :, :, 3] and
  • x[4, ..., 5, :] to x[4, :, :, 5, :].

...表示尽可能多的表示所需的冒号来组成一个完整的索引元组。例如,如果x是一个5D的数组,那么

  • x[1, 2, ...] 等同于 x[1, 2, :, :, :],
  • x[..., 3] 等同于 x[:, :, :, :, 3] 和
  • x[4, ..., 5, :] 等同于 x[4, :, :, 5, :]。
>>> a = np.arange(3*4*5).reshape(3, 4, 5)
>>> a.shape
(3, 4, 5)
>>> a
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, 32, 33, 34],
        [35, 36, 37, 38, 39]],

       [[40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49],
        [50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59]]])
>>> a[1, ...]
array([[20, 21, 22, 23, 24],
       [25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34],
       [35, 36, 37, 38, 39]])
>>> a[0, 1, ...]
array([5, 6, 7, 8, 9])
>>> a[..., 3]
array([[ 3,  8, 13, 18],
       [23, 28, 33, 38],
       [43, 48, 53, 58]])
>>>

Iterating over multidimensional arrays is done with respect to the first axis:

多维数组的迭代是在第一维度上完成的。

>>> a = np.arange(6).reshape(3, 2)
>>> a
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> for i, row in enumerate(a):
...     print("i:", i, "row:", row)
...
i: 0 row: [0 1]
i: 1 row: [2 3]
i: 2 row: [4 5]

However, if one wants to perform an operation on each element in the array, one can use the flat attribute which is an iterator over all the elements of the array:

然而,如果想对数组中的每个元素执行运算,可以使用numpy.ndarray.flat属性,它是一个数组中所有元素的迭代器。

>>> a
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> for e in a.flat:
...     print(e**2)
...
0
1
4
9
16
25
>>>
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1026284.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号