Python - NumPy

NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。

混淆速记

np.max, np.maximum

np.maximum: compare two arrays and returns a new array containing the element-wise maxima

np.max: return the maximum of an array or maximum along an axis.

1
2
3
4
5
6
import numpy as np
a = np.array([[-1,2,3],[4,-5,6]])
print(np.max(a,axis=1))
# [3 6]
print(np.maximum(0,a))
# [[0,2,3],[4,0,6]]

np.random.normal, np.ranodm.normn

1
numpy.random.randn(d0, d1, ..., dn)

Return a sample (or samples) from the “standard normal” distribution.

1
numpy.random.normal(loc=0.0, scale=1.0, size=None)

Draw random samples from a normal (Gaussian) distribution.

dot,outer,*

dot:矩阵乘法

1
2
3
4
5
6
7
a = np.array([[1,2],[3,4]])
# [[1 2]
# [3 4]]
b = np.array([5,6])
# [5 6] shape = (2,1)
print(np.dot(a,b))
# [17 39]

outer:接受两个数组a和b,分别将a和b展开为一维数组,两个for循环遍历a和b,循环内做乘法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
a = np.array([[1,2],[3,4]])
# [[1 2]
# [3 4]]
b = np.array([5,6])
# [5 6] shape = (2,1)
print(np.outer(a,b))
# [[ 5 6]
# [10 12]
# [15 18]
# [20 24]]
#####等价于#####
a = [1,2,3,4]
b = [5,6]
result = []
for i in a:
t = []
for j in b:
t.append(i*j)
result.append(t)
print(result)
# [[5, 6], [10, 12], [15, 18], [20, 24]]

*:对应元素相乘,要求形状相同。

Ndarray对象

NumPy 中定义的最重要的对象是称为 ndarray 的 N 维数组类型。 它描述相同类型的元素集合。 可以使用基于零的索引访问集合中的项目。

ndarray中的每个元素在内存中使用相同大小的块。 ndarray中的每个元素是数据类型对象的对象(称为 dtype)。

基本的ndarray是使用 NumPy 中的数组函数创建的

1
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

Screen Shot 2018-06-15 at 4.03.50 PM

一维数组

1
2
3
4
import numpy as np
a = np.array([1,2,3])
print a
#[1, 2, 3]

二维数组

1
2
3
4
5
import numpy as np
a = np.array([[1, 2], [3, 4]])
print a
# [[1, 2]
# [3, 4]]

数组属性

ndarray.shape

这一数组属性返回一个包含数组维度的元组,它也可以用于调整数组大小。

1
2
3
4
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(a.shape)
# (2, 3)
1
2
3
4
5
6
7
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
a.shape=(3,2) # 调整数组大小
print(a)
# [[1 2]
# [3 4]
# [5 6]]

NumPy 也提供了reshape函数来调整数组大小。

1
2
3
4
5
6
7
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2)
print (b)
# # [[1 2]
# # [3 4]
# # [5 6]]

数组创建

numpy.empty()

它创建指定形状和dtype的未初始化数组。

1
numpy.empty(shape, dtype = float, order = 'C')

Screen Shot 2018-06-15 at 4.14.21 PM

shape参数以”( )”或者“[ ]”传递整数元组

1
2
3
4
5
6
import numpy as np
x = np.empty([3,2], dtype = int)
print (x)
# [[-9223372036854775808 1152930269942935736]
# [ 3401169227572248579 7795500255900756322]
# [ 4298072681 844429423207176]]

数组元素为随机值,因为它们未初始化。

numpy.zeros()

返回特定大小,以 0 填充的新数组。

1
numpy.zeros(shape, dtype = float, order = 'C')
1
2
3
4
5
# 含有 5 个 0 的数组,默认类型为 float
import numpy as np
x = np.zeros(5)
print (x)
# [0. 0. 0. 0. 0.]
1
2
3
4
import numpy as np
x = np.zeros((5,), dtype = np.int)
print (x)
# [0 0 0 0 0]
1
2
3
4
5
6
7
8
import numpy as np
x = np.zeros((5,2), dtype = np.int)
print (x)
# [[0 0]
# [0 0]
# [0 0]
# [0 0]
# [0 0]]

numpy.ones()

返回特定大小,以 1 填充的新数组。

1
2
3
4
5
6
7
8
9
import numpy as np
x = np.ones(5)
print(x)
# [1. 1. 1. 1. 1.]
x = np.ones([2,2], dtype = int)
print(x)
# [[1 1]
# [1 1]]

numpy.asarray()

此函数类似于numpy.array,除了它有较少的参数。 这个例程对于将 Python 序列转换为ndarray非常有用。

1
numpy.asarray(a, dtype = None, order = None)

a 任意形式的输入参数,比如列表、列表的元组、元组、元组的元组、元组的列表

1
2
3
4
5
6
7
# 将列表转换为 ndarray
import numpy as np
x = [1,2,3]
a = np.asarray(x)
print (a)
# [1 2 3]
1
2
3
4
5
6
7
# 设置了 dtype
import numpy as np
x = [1,2,3]
a = np.asarray(x, dtype = float)
print (a)
# [1. 2. 3.]
1
2
3
4
5
6
7
# 来自元组的 ndarray
import numpy as np
x = (1,2,3)
a = np.asarray(x)
print (a)
# [1 2 3]

numpy.fromiter()

此函数从任何可迭代对象构建一个ndarray对象,返回一个新的一维数组。

1
numpy.fromiter(iterable, dtype, count = -1)

以下示例展示了如何使用内置的range()函数返回列表对象。 此列表的迭代器用于形成ndarray对象。

1
2
3
4
5
6
7
8
9
10
11
# 使用 range 函数创建列表对象
import numpy as np
list = range(5)
print (list)
# range(0, 5)
it = iter(list)
# 使用迭代器创建 ndarray
x = np.fromiter(it, dtype = float)
print(x)
# [0. 1. 2. 3. 4.]

numpy.arange()

这个函数返回ndarray对象,包含给定范围内的等间隔值。

1
numpy.arange(start, stop, step, dtype)

Screen Shot 2018-06-17 at 10.23.27 AM

1
2
3
4
import numpy as np
x = np.arange(5)
print (x)
# [0 1 2 3 4]
1
2
3
4
5
import numpy as np
# 设置了 dtype
x = np.arange(5, dtype = float)
print (x)
# [0. 1. 2. 3. 4.]
1
2
3
4
5
# 设置了起始值和终止值参数
import numpy as np
x = np.arange(10,20,2)
print (x)
# [10 12 14 16 18]

numpy.linspace

此函数类似于arange()函数。 在此函数中,指定了范围之间的均匀间隔数量,而不是步长。

1
numpy.linspace(start, stop, num, endpoint, retstep, dtype)

Screen Shot 2018-06-17 at 10.27.52 AM

1
2
3
4
5
6
7
8
9
10
import numpy as np
x = np.linspace(10,20,5)
print (x)
# [10. 12.5 15. 17.5 20. ]
x = np.linspace(10,20, 5, endpoint = False)
# [10. 12. 14. 16. 18.]
x = np.linspace(1,2,5, retstep = True)
# (array([ 1. , 1.25, 1.5 , 1.75, 2. ]), 0.25)

numpy.logspace()

此函数返回一个ndarray对象,其中包含在对数刻度上均匀分布的数字。 刻度的开始和结束端点是某个底数的幂,通常为 10。

1
numpy.logscale(start, stop, num, endpoint, base, dtype)

Screen Shot 2018-06-17 at 10.31.34 AM

1
2
3
4
5
6
7
8
9
10
import numpy as np
# 默认底数是 10
a = np.logspace(1.0, 2.0, num = 10)
print (a)
# [ 10. 12.91549665 16.68100537 21.5443469 27.82559402
# 35.93813664 46.41588834 59.94842503 77.42636827 100. ]
a = np.logspace(1,10,num = 10, base = 2)
print (a)
# [ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]

切片和索引

切片

ndarray对象的内容可以通过索引或切片来访问和修改, ndarray对象中的元素遵循基于零的索引。 有三种可用的索引方法类型: 字段访问,基本切片高级索引

基本切片是 Python 中基本切片概念到 n 维的扩展。 通过将startstopstep参数提供给内置的slice函数来构造一个 Python slice对象。 此slice对象被传递给数组来提取数组的一部分。

1
2
3
4
5
6
7
import numpy as np
a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]
s = slice(2,7,2)
print (a[s])
# [2 4 6]

在上面的例子中,ndarray对象由arange()函数创建。 然后,分别用起始,终止和步长值272定义切片对象。 当这个切片对象传递给ndarray时,会对它的一部分进行切片,从索引27,步长为2

通过将由冒号分隔的切片参数(start:stop:step)直接提供给ndarray对象,也可以获得相同的结果。

1
2
3
4
5
import numpy as np
a = np.arange(10)
b = a[2:7:2]
print (b)
# [2 4 6]

如果只输入一个参数,则将返回与索引对应的单个项目。 如果使用a:,则从该索引向后的所有项目将被提取。 如果使用两个参数(以:分隔),则对两个索引(不包括停止索引)之间的元素以默认步骤进行切片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 对单个元素进行切片
import numpy as np
a = np.arange(10)
b = a[5]
print (b)
# 5
# 对始于索引的元素进行切片
a = np.arange(10)
print (a[2:])
# [2 3 4 5 6 7 8 9]
# 对索引之间的元素进行切片
a = np.arange(10)
print (a[2:5])
# [2 3 4]

上面的描述也可用于多维ndarray

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a)
# [[1 2 3]
# [3 4 5]
# [4 5 6]]
# 对始于索引的元素进行切片
print (a[1:])
# [[3 4 5]
# [4 5 6]]

切片还可以包括省略号(...),来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的ndarray

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a)
# [[1 2 3]
# [3 4 5]
# [4 5 6]]
# 这会返回第二列元素的数组:
print ('第二列的元素是:')
print (a[...,1])
# [2 4 5]
# 现在我们从第二行切片所有元素:
print ('第二行的元素是:' )
print (a[1,...])
# [3 4 5]
# 现在我们从第二列向后切片所有元素:
print ('第二列及其剩余元素是:' )
print (a[...,1:])
# [[2 3]
# [4 5]
# [5 6]]

高级索引

高级索引始终返回数据的副本。 与此相反,切片只提供了一个视图。

有两种类型的高级索引:整数和布尔值。

整数索引

这种机制有助于基于 N 维索引来获取数组中任意元素。 每个整数数组表示该维度的下标值。 当索引的元素个数就是目标ndarray的维度时,会变得相当直接。

以下示例获取了ndarray对象中每一行指定列的一个元素。 因此,行索引包含所有行号,列索引指定要选择的元素。

1
2
3
4
5
6
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]]
print (y)
# [1 4 5]

该结果包括数组中(0,0)(1,1)(2,0)位置处的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(x)
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
z = [rows,cols]
print(z)
# [array([[0, 0],[3, 3]]),
# array([[0, 2],[0, 2]])]
y = x[rows,cols]
print(y)
# [[ 0 2]
# [ 9 11]]
w = x[[0,0,3,3],[0,2,0,2]]
print(w)
# [ 0 2 9 11]

示例获取了 4X3 数组中的每个角处的元素。 行索引是[0,0][3,3],而列索引是[0,2][0,2]

高级和基本索引可以通过使用切片:或省略号...与索引数组组合。 以下示例使用slice作为列索引和高级索引。 当切片用于两者时,结果是相同的。 但高级索引会导致复制,并且可能有不同的内存布局。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(x)
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
# 切片
z = x[1:4,1:3]
print(z)
# [[ 4 5]
# [ 7 8]
# [10 11]]
# 对列使用高级索引
y = x[1:4,[1,2]]
print(y)
# [[ 4 5]
# [ 7 8]
# [10 11]]

布尔索引

当结果对象是布尔运算(例如比较运算符)的结果时,将使用此类型的高级索引。

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print(x)
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
# 现在我们会打印出大于 5 的元素
print ('大于 5 的元素是:' )
print (x[x > 5])
# 大于 5 的元素是:
# [ 6 7 8 9 10 11]
1
2
3
4
import numpy as np
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print (a[~np.isnan(a)])
# [1. 2. 3. 4. 5.]

这个例子使用了~(取补运算符)来过滤NaN

1
2
3
4
import numpy as np
a = np.array([1, 2+6j, 5, 3.5+5j])
print (a[np.iscomplex(a)])
# [2. +6.j 3.5+5.j]

示例显示如何从数组中过滤掉非复数元素。

NumPy广播

广播是指 NumPy 在算术运算期间处理不同形状的数组的能力。 对数组的算术运算通常在相应的元素上进行。 如果两个阵列具有完全相同的形状,则这些操作被无缝执行。

如果两个数组的维数不相同,则元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。 较小的数组会广播到较大数组的大小,以便使它们的形状可兼容。

Scalar and One-Dimensional Array

1
2
3
4
5
import numpy as np
a = np.array([1,2,3])
b = 2
c = a+b
# c = [1+2,2+2,3+2]=[3,4,5]

Scalar and Two-Dimensional Array

1
2
3
4
5
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = 2
c = a+b
# [[1+2,2+2,3+2],[4+2,5+2,6+2]]=[[3,4,5],[6,7,8]]

One-Dimensional and Two-Dimensional Arrays

1
2
3
4
5
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = np.array([-1,-2,-3])
c = a+b
# [[0,0,0],[3,3,3]]

Definition

Element-wise operations on arrays are only valid when the arrays’ shapes are either equal or compatible. The equal shapes case is trivial - this is the stretched array from the example above. What does “compatible” mean, though?

To determine if two shapes are compatible, Numpy compares their dimensions, starting with the trailing ones and working its way backwards. If two dimensions are equal, or if one of them equals 1, the comparison continues. Otherwise, you’ll see a ValueError raised (saying something like “operands could not be broadcast together with shapes …”). When one of the shapes runs out of dimensions (because it has less dimensions than the other shape), Numpy will use 1 in the comparison process until the other shape’s dimensions run out as well. Once Numpy determines that two shapes are compatible, the shape of the result is simply the maximum of the two shapes’ sizes in each dimension.

Example

The definition above is precise and complete; to get a feel for it, we’ll need a few examples.

I’m using the Numpy convention of describing shapes as tuples. macros is a 4-by-3 array, meaning that it has 4 rows with 3 columns each, or 4x3. The Numpy way of describing the shape of macros is (4, 3):

1
2
In [80]: macros.shape
Out[80]: (4, 3)

When we computed the caloric table using broadcasting, what we did was an operation between macros- a (4, 3) array, and cal_per_macro, a (3,) array [4]. Therefore, following the broadcasting rules outlined above, the shape (3,) is left-padded with 1 to make comparison with (4, 3) possible. The shapes are then deemed compatible and the result shape is (4, 3), which is exactly what we observed.

Schematically:

1
2
3
(4, 3) (4, 3)
== padding ==> == result ==> (4, 3)
(3,) (1, 3)

Here’s another example, broadcasting between a 3-D and a 1-D array:

1
2
3
(3,) (1, 1, 3)
== padding ==> == result ==> (5, 4, 3)
(5, 4, 3) (5, 4, 3)

Note, however, that only left-padding with 1s is allowed. Therefore:

1
2
3
(5,) (1, 1, 5)
== padding ==> ==> error (5 != 3)
(5, 4, 3) (5, 4, 3)

Theoretically, had the broadcasting rules been less rigid - we could say that this broadcasting is valid if we right-pad (5,) with 1s. However, this is not how the rules are defined - therefore these shapes are incompatible.

Broadcasting is valid between higher-dimensional arrays too:

1
2
3
(5, 4, 3) (1, 5, 4, 3)
== padding ==> == result ==> (6, 5, 4, 3)
(6, 5, 4, 3) (6, 5, 4, 3)

Also, in the beginning of the article I mentioned that broadcasting does not necessarily occur between arrays of different number of dimensions. It’s perfectly valid to broadcast arrays with the same number of dimensions, as long as they are compatible:

1
2
3
(5, 4, 1)
== no padding needed ==> result ==> (5, 4, 3)
(5, 1, 3)

NumPy数组迭代

NumPy 包包含一个迭代器对象numpy.nditer

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print(a)
# [[ 0 5 10 15]
# [20 25 30 35]
# [40 45 50 55]]
for ele in np.nditer(a):
print(ele)
# 0 5 10 15 20 25 30 35 40 45 50 55

迭代顺序

F/C order

Screen Shot 2018-06-18 at 3.53.25 PM

修改数组的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print(a)
# [[ 0 5 10 15]
# [20 25 30 35]
# [40 45 50 55]]
for ele in np.nditer(a, op_flags=['readwrite']):
ele[...] = 2*ele
print(a)
# [[ 0 10 20 30]
# [ 40 50 60 70]
# [ 80 90 100 110]]

外部循环

nditer类的构造器拥有flags参数,如果其值是external_loop 给出的值是具有多个值的一维数组,而不是零维数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print(a)
# [[ 0 5 10 15]
# [20 25 30 35]
# [40 45 50 55]]
for ele in np.nditer(a, flags=['external_loop'],order='F'):
print(ele)
# [ 0 20 40]
# [ 5 25 45]
# [10 30 50]
# [15 35 55]
for ele in np.nditer(a, flags=['external_loop']):
print(ele)
# [ 0 5 10 15 20 25 30 35 40 45 50 55]

NumPy数组操作

提供了几个处理ndarray对象中的元素的方法

修改数组形状

Screen Shot 2018-06-18 at 4.01.08 PM

numpy.reshape

这个函数在不改变数据的条件下修改形状,它接受如下参数:

1
numpy.reshape(arr, newshape, order')

其中:

  • arr:要修改形状的数组
  • newshape:整数或者整数数组,新的形状应当兼容原有形状
  • order'C'为 C 风格顺序,'F'为 F 风格顺序,'A'为保留原顺序。
1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a = np.arange(8)
print(a)
# [0 1 2 3 4 5 6 7]
b = a.reshape(4,2)
print(b)
# [[0 1]
# [2 3]
# [4 5]
# [6 7]]

numpy.ndarray.flat

该函数返回数组上的一维迭代器,行为类似 Python 内建的迭代器。

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
a = np.array([2,4,6,8,10,12,14,16]).reshape(4,2)
print(a)
# [[ 2 4]
# [ 6 8]
# [10 12]
# [14 16]]
print(a.flat[4])
# 10

numpy.ndarray.flatten

该函数返回折叠为一维的数组副本,函数接受下列参数:

1
ndarray.flatten(order)

其中:

  • order'C' — 按行,'F' — 按列,'A' — 原顺序,'k' — 元素在内存中的出现顺序。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import numpy as np
    a = np.array([2,4,6,8,10,12,14,16]).reshape(4,2)
    print(a)
    # [[ 2 4]
    # [ 6 8]
    # [10 12]
    # [14 16]]
    print(a.flatten())
    # [ 2 4 6 8 10 12 14 16]
    print(a.flatten(order='F'))
    # [ 2 6 10 14 4 8 12 16]

numpy.ravel

这个函数返回展开的一维数组,并且按需生成副本。返回的数组和输入数组拥有相同数据类型。这个函数接受两个参数。

1
numpy.ravel(a, order)

构造器接受下列参数:

  • order'C' — 按行,'F' — 按列,'A' — 原顺序,'k' — 元素在内存中的出现顺序。
1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
a = np.array([2,4,6,8,10,12,14,16]).reshape(4,2)
print(a)
# [[ 2 4]
# [ 6 8]
# [10 12]
# [14 16]]
print(np.ravel(a))
# [ 2 4 6 8 10 12 14 16]
print(np.ravel(a,order='F'))
# [ 2 6 10 14 4 8 12 16]

数组翻转

Screen Shot 2018-06-18 at 4.11.26 PM

numpy.transpose()

这个函数翻转给定数组的维度。如果可能的话它会返回一个视图。函数接受下列参数:

1
numpy.transpose(arr, axes)

其中:

  • arr:要转置的数组
  • axes:整数的列表,对应维度,通常所有维度都会翻转。
1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a = np.array([2,4,6,8,10,12,14,16]).reshape(4,2)
print(a)
# [[ 2 4]
# [ 6 8]
# [10 12]
# [14 16]]
print(np.transpose(a))
# [[ 2 6 10 14]
# [ 4 8 12 16]]

numpy.ndarray.T

该函数属于ndarray类,行为类似于numpy.transpose

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a = np.array([2,4,6,8,10,12,14,16]).reshape(4,2)
print(a)
# [[ 2 4]
# [ 6 8]
# [10 12]
# [14 16]]
print(a.T)
# [[ 2 6 10 14]
# [ 4 8 12 16]]

numpy.rollaxis()

该函数向后滚动特定的轴,直到一个特定位置。这个函数接受三个参数:

1
numpy.rollaxis(arr, axis, start)

其中:

  • arr:输入数组
  • axis:要向后滚动的轴,其它轴的相对位置不会改变
  • start:默认为零,表示完整的滚动。会滚动到特定位置。
1
2
3
#有些数据集的图片默认图片格式是[chanel][height][width], 然而有些地方显示图片是[height][width][chanel], 这就需要改变一下图片轴的次序。
# old_img是3*32*32的,new_img是32*32*3的
newimg = np.rollaxis(old_img, 0, 3) # 把轴0放到轴3的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
a = np.arange(8)
a = a.reshape(2,4)
print(a)
# [[0 1 2 3]
# [4 5 6 7]]
#将轴1滚动到轴0,(2,4)->(4,2)
print(np.rollaxis(a,1))
# [[0 4]
# [1 5]
# [2 6]
# [3 7]]
#即轴1滚动到轴1,不变
print(np.rollaxis(a,1,1))
# [[0 1 2 3]
# [4 5 6 7]]

numpy.swapaxes()

该函数交换数组的两个轴。对于 1.10 之前的 NumPy 版本,会返回交换后数组的试图。这个函数接受下列参数:

1
numpy.swapaxes(arr, axis1, axis2)
  • arr:要交换其轴的输入数组
  • axis1:对应第一个轴的整数
  • axis2:对应第二个轴的整数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import numpy as np
    a = np.arange(16)
    a = a.reshape(2,2,4)
    print(a)
    # [[[ 0 1 2 3]
    # [ 4 5 6 7]]
    #
    # [[ 8 9 10 11]
    # [12 13 14 15]]]
    #就是将第三个维度和第二个维度交换,
    # 数字7来说,之前的索引是(0,1,3),那么交换之后,就应该是(0,3,1)
    print(np.swapaxes(a,2,1))
    # [[[ 0 4]
    # [ 1 5]
    # [ 2 6]
    # [ 3 7]]
    #
    # [[ 8 12]
    # [ 9 13]
    # [10 14]
    # [11 15]]]

修改维度

Screen Shot 2018-06-19 at 3.32.30 PM

numpy.expand_dims()

函数通过在指定位置插入新的轴来扩展数组形状。该函数需要两个参数:

1
numpy.expand_dims(arr, axis)

其中:

  • arr:输入数组
  • axis:新轴插入的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
x = np.array([1,2])
print(x,x.shape)
# [1 2],(2,)
#
y = np.expand_dims(x,axis=0)
print(y,y.shape)
# [[1 2]],(1, 2)
y = np.expand_dims(x,axis=1)
print(y,y.shape)
# [[1]
# [2]] (2, 1)

numpy.squeeze()

函数从给定数组的形状中删除一维条目,即shape=(x,..,1,…y),那么就会变成(x,.,y)

1
numpy.squeeze(arr, axis)

其中:

  • arr:输入数组
  • axis:整数或整数元组,用于选择形状中单一维度条目的子集

数组连接

Screen Shot 2018-06-19 at 3.43.35 PM

numpy.concatenate()

数组的连接是指连接。 此函数用于沿指定轴连接相同形状的两个或多个数组。 该函数接受以下参数。

1
numpy.concatenate((a1, a2, ...), axis)

其中:

  • a1, a2, ...:相同类型的数组序列
  • axis:沿着它连接数组的轴,默认为 0,即添加在下方;axis=1使添加在右方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
a = np.array([[1,2],[3,4]])
print(a)
# [[1 2]
# [3 4]]
b = np.array([[5,6],[7,8]])
print(b)
# [[5 6]
# [7 8]]
print(np.concatenate((a,b)))
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
print(np.concatenate((a,b),axis=1))
# [[1 2 5 6]
# [3 4 7 8]]

numpy.stack()

此函数沿新轴连接数组序列。 此功能添加自 NumPy 版本 1.10.0。 需要提供以下参数。

1
numpy.stack(arrays, axis)

其中:

  • arrays:相同形状的数组序列
  • axis:返回数组中的轴,输入数组沿着它来堆叠
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
print(np.stack((a,b)))
# [[1 2 3]
# [4 5 6]]
# shape = (2,3)
print(np.stack((a,b),axis=1))
# [[1 4]
# [2 5]
# [3 6]]
# shape = (3,2)

数组分割

Screen Shot 2018-06-19 at 3.50.55 PM

numpy.split()

该函数沿特定的轴将数组分割为子数组。函数接受三个参数:

1
numpy.split(ary, indices_or_sections, axis)

其中:

  • ary:被分割的输入数组
  • indices_or_sections:可以是整数,表明要从输入数组创建的,等大小的子数组的数量。 如果此参数是一维数组,则其元素表明要创建新子数组的点。
  • axis:默认为 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
a = np.arange(9)
print ('第一个数组:')
print (a)
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
# 第一个数组:
# [0 1 2 3 4 5 6 7 8]
# 将数组分为三个大小相等的子数组:
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
# 将数组在一维数组中表明的位置分割:
# [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]

如果之前的shape是(x,y),那么分割之后是(x/2 , y) 或者 (x , y/2)

元素添加/删除

Screen Shot 2018-06-20 at 9.10.44 AM

numpy.resize()

此函数返回指定大小的新数组。 如果新大小大于原始大小,则包含原始数组中的元素的重复副本。 该函数接受以下参数。

1
numpy.resize(arr, shape)

其中:

  • arr:要修改大小的输入数组
  • shape:返回数组的新形状
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(a)
# [[1 2 3]
# [4 5 6]]
b = np.resize(a,(3,2))#效果等于reshape
print(b)
# [[1 2]
# [3 4]
# [5 6]]
b = np.resize(a,(3,5))#不能用reshape
print(b)
# [[1 2 3 4 5]
# [6 1 2 3 4]
# [5 6 1 2 3]]

numpy.append()

此函数在输入数组的末尾添加值。 附加操作不是原地的,而是分配新的数组。 此外,输入数组的维度必须匹配否则将生成ValueError

函数接受下列函数:

1
numpy.append(arr, values, axis)

其中:

  • arr:输入数组

  • values:要向arr添加的值,比如和arr形状相同(除了要添加的轴)

  • axis:沿着它完成操作的轴。如果没有提供,两个参数都会被展开。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import numpy as np
    a = np.array([[1,2,3],[4,5,6]])
    print(a)
    # [[1 2 3]
    # [4 5 6]]
    #没有提供axis,则展开所有轴
    print(np.append(a,[7,8,9]))
    # [1 2 3 4 5 6 7 8 9]
    #添加数组维度必须原来的匹配,此例中原来数组是shape=(2,3),则axis=0,那么列的维度相同,shape=(x,3)
    print(np.append(a,[[7,8,9],[5,5,5],[1,2,3]],axis=0))
    # [[1 2 3]
    # [4 5 6]
    # [7 8 9]
    # [5 5 5]
    # [1 2 3]]
    #axis=1,则竖向添加,行的维度相同,shape=(2,x)
    print(np.append(a,[[5,5,5,5],[7,8,9,10]],axis=1))
    # [[ 1 2 3 5 5 5 5]
    # [ 4 5 6 7 8 9 10]]

numpy.insert()

此函数在给定索引之前,沿给定轴在输入数组中插入值。 如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。

insert()函数接受以下参数:

1
numpy.insert(arr, obj, values, axis)

其中:

  • arr:输入数组
  • obj:在其之前插入值的索引
  • values:要插入的值
  • axis:沿着它插入的轴,如果未提供,则输入数组会被展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
a = np.array([[1,2],[3,4],[5,6]])
print(a)
# [[1 2]
# [3 4]
# [5 6]]
#在index=3插入【11,12】
print(np.insert(a,3,[11,12]))
# [ 1 2 3 11 12 4 5 6]
print(np.insert(a,1,[11],axis=0))
# [[ 1 2]
# [11 11]
# [ 3 4]
# [ 5 6]]
print(np.insert(a,1,11,axis=1))
# [[ 1 11 2]
# [ 3 11 4]
# [ 5 11 6]]

numpy.delete()

此函数返回从输入数组中删除指定子数组的新数组。 与insert()函数的情况一样,如果未提供轴参数,则输入数组将展开。 该函数接受以下参数:

1
Numpy.delete(arr, obj, axis)

其中:

  • arr:输入数组
  • obj:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组
  • axis:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9,10,11,12]).reshape(3,4)
print(a)
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
print(np.delete(a,5))#删除index=5的值
# [ 1 2 3 4 5 7 8 9 10 11 12]
#删除第二行
print(np.delete(a,1,axis=1))
# [[ 1 3 4]
# [ 5 7 8]
# [ 9 11 12]]
a = np.array([1,2,3,4,5,6,7,8,9,10])
print(np.delete(a,np.s_[::2]))
# [ 2 4 6 8 10]

numpy.unique()

此函数返回输入数组中的去重元素数组。 该函数能够返回一个元组,包含去重数组和相关索引的数组。 索引的性质取决于函数调用中返回参数的类型。

1
numpy.unique(arr, return_index, return_inverse, return_counts)

其中:

  • arr:输入数组,如果不是一维数组则会展开
  • return_index:如果为true,返回输入数组中的元素下标
  • return_inverse:如果为true,返回去重数组的下标,它可以用于重构输入数组
  • return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
print(a)
# [5 2 6 2 7 5 6 8 2 9]
#返回去重之后的数组
u = np.unique(a)
print(u)
# [2 5 6 7 8 9]
# 去重数组的索引
u,indices = np.unique(a,return_index=True)
print(indices)
#[1 0 2 4 7 9]
#
u,counts = np.unique(a,return_counts=True)
print(counts)
# [3 2 2 1 1 1]

NumPy位操作

Screen Shot 2018-06-20 at 3.24.42 PM

bitwise_and()

通过np.bitwise_and()函数对输入数组中的整数的二进制表示的相应位执行位与运算。

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
a = 13
b =17
print(bin(a))
# 0b1101
print(bin(b))
# 0b10001
print(np.bitwise_and(13,17))
# 1

bitwise_or()

通过np.bitwise_or()函数对输入数组中的整数的二进制表示的相应位执行位或运算。

left_shift()

将数组元素的二进制表示中的位向左移动到指定位置,右侧附加相等数量的 0。

1
2
3
4
5
6
a = 13
print(bin(a))
# 0b1101
a_ = np.left_shift(a,2)
print(bin(a_),a_)
# 0b110100 52

right_shift()

将数组元素的二进制表示中的位向右移动到指定位置,左侧附加相等数量的 0。

NumPy字符串函数

Screen Shot 2018-06-20 at 3.34.40 PM

这些函数在字符数组类(numpy.char)中定义。 numpy.char类中的上述函数在执行向量化字符串操作时非常有用。

numpy.char.add()

函数执行按元素的字符串连接。

1
2
3
4
5
6
import numpy as np
print(np.char.add(['hello'],['xyz']))
# ['helloxyz']
print(np.char.add(['hello','why'],['xyz','like this']))
# ['helloxyz' 'whylike this']

numpy.char.multiply()

1
2
print(np.char.multiply("Wq",3))
# WqWqWq

numpy.char.center()

此函数返回所需宽度的数组,以便输入字符串位于中心,并使用fillchar在左侧和右侧进行填充。

1
2
print(np.char.center('hello',10,fillchar="@"))
# @@hello@@@

numpy.char.capitalize()

函数返回字符串的副本,其中第一个字母大写

1
2
print np.char.capitalize('hello world')
# Hello world

numpy.char.title()

返回输入字符串的按元素标题转换版本,其中每个单词的首字母都大写。

1
2
print np.char.title('hello how are you?')
# Hello How Are You?

numpy.char.lower()

函数返回一个数组,其元素转换为小写。它对每个元素调用str.lower

1
2
3
4
print(np.char.lower('HeLLo'))
# hello
print(np.char.lower(["HeLLO",'WORld']))
# ['hello' 'world']

numpy.char.upper()

函数返回一个数组,其元素转换为大写。它对每个元素调用str.upper

numpy.char.split()

此函数返回输入字符串中的单词列表。 默认情况下,空格用作分隔符。 否则,指定的分隔符字符用于分割字符串。

1
2
3
4
print (np.char.split ('hello how are you?') )
# ['hello', 'how', 'are', 'you?']
print (np.char.split ('YiibaiPoint,Hyderabad,Telangana', sep = ','))
# ['YiibaiPoint', 'Hyderabad', 'Telangana']

numpy.char.splitlines()

函数返回数组中元素的单词列表,以换行符分割。'\n''\r''\r\n'都会用作换行符。

1
2
3
4
print (np.char.splitlines('hello\nhow are you?') )
# ['hello', 'how are you?']
print (np.char.splitlines('hello\rhow are you?'))
# ['hello', 'how are you?']

numpy.char.strip()

函数返回数组的副本,其中元素移除了开头或结尾处的特定字符。

1
2
3
4
print np.char.strip('ashok arora','a')
# shok aror
print np.char.strip(['arora','admin','java'],'a')
# ['ror' 'dmin' 'jav']

numpy.char.join()

这个函数返回一个字符串,其中单个字符由特定的分隔符连接。

1
2
3
4
print np.char.join(':','dmy')
print np.char.join([':','-'],['dmy','ymd'])
# d:m:y
# ['d:m:y' 'y-m-d']

numpy.char.replace()

这个函数返回字符串副本,其中所有字符序列的出现位置都被另一个给定的字符序列取代。

1
2
3
import numpy as np
print np.char.replace ('He is a good boy', 'is', 'was')
# He was a good boy

NumPy算数函数

NumPy 提供标准的三角函数,算术运算的函数,复数处理函数等。

三角函数

参考

舍入函数

Screen Shot 2018-06-21 at 9.31.30 AM

1
2
3
4
5
6
7
8
9
10
import numpy as np
a = np.array([1.0,5.55, 123, 0.567, 25.532])
print(np.around(a))
# [1. 6. 123. 1. 26.]
print(np.around(a,decimals=1))
# [1. 5.6 123. 0.6 25.5]
print(np.around(a,decimals=-1))
# [0. 10. 120. 0. 30.]

numpy.floor()/.ceil()

floor() 此函数返回不大于输入参数的最大整数

ceil() 返回输入值的上限

1
2
3
4
5
6
import numpy as np
a = np.array([-1.7, 1.5, -0.2, 0.6, 10])
print(np.floor(a))
# [-2. 1. -1. 0. 10.]
print(np.ceil(a))
# [-1. 2. -0. 1. 10.]

NumPy算数运算

用于执行算术运算(如add()subtract()multiply()divide())的输入数组必须具有相同的形状或符合数组广播规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
a = np.arange(9).reshape(3,3)
print(a)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
b = np.array([10,10,10])
print(a+b) #等价于np.add(a,b)
# [[10 11 12]
# [13 14 15]
# [16 17 18]]
print(a-b) #等价于np.subtract(a,b)
# [[-10 -9 -8]
# [ -7 -6 -5]
# [ -4 -3 -2]]
print(a*b) #等价于np.multiply(a,b)
# [[ 0 10 20]
# [30 40 50]
# [60 70 80]]
print(a/b) #等价于np.divide(a,b)
# [[0. 0.1 0.2]
# [0.3 0.4 0.5]
# [0.6 0.7 0.8]]

numpy.reciprocal()

此函数返回参数逐元素的倒数,。 由于 Python 处理整数除法的方式,对于绝对值大于 1 的整数元素,结果始终为 0, 对于整数 0,则发出溢出警告。

1
2
3
4
5
6
7
import numpy as np
a = np.array([0.25, 1.33, 1, 0, 100])
print(np.reciprocal(a))
# [4. 0.7518797 1. inf 0.01 ]
b = np.array([100],dtype=int)
print(np.reciprocal(b))
# [0]

numpy.power()

此函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。

1
2
3
4
5
6
7
import numpy as np
a = np.array([2,3,4])
print(np.power(a,2))
# [ 4 9 16]
b = np.array([1,2,3])
print(np.power(a,b))
# [ 2 9 64]

numpy.mod()

此函数返回输入数组中相应元素的除法余数。 函数numpy.remainder()也产生相同的结果。

1
2
3
4
5
6
7
import numpy as np
a = np.array([10,20,30])
b = np.array([3,5,7])
print(np.mod(a,b))
# [1 0 2]
print(np.remainder(a,b))
# [1 0 2]

NumPy统计函数

NumPy 有很多有用的统计函数,用于从数组中给定的元素中查找最小,最大,百分标准差和方差等。

numpy.amin()/.amax()

从给定数组中的元素沿指定轴返回最小值和最大值。

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print(a)
# [[3 7 5]
# [8 4 3]
# [2 4 9]]
print(np.amin(a,1))
# [3 3 2]
print(np.amin(a,0))
# [2 4 3]
print(np.amin(a))
# 2

numpy.ptp()

返回沿轴的值的范围(最大值 - 最小值)。

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print(a)
# [[3 7 5]
# [8 4 3]
# [2 4 9]]
print(np.ptp(a))
# 7 (9-2)
print(np.ptp(a,axis=1))
# [4 5 7]
print(np.ptp(a,0))
# [6 3 6]

numpy.percentile()

Screen Shot 2018-06-21 at 9.56.48 AM

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a = np.array([[30,40,70],[80,20,10]])
print(a)
# [[30 40 70]
# [80 20 10]
print(np.percentile(a,50))# #50%的分位数,就是a里排序之后的中位数
# 35.0
print(np.percentile(a,50,axis=1))
# [40. 20.]
print(np.percentile(a,50,axis=0))
# [55. 30. 40.]

numpy.median()

1
numpy.median(a,axis)

numpy.mean()

1
numpy.mean(a,axis)

numpy.average()

加权平均值是由每个分量乘以反映其重要性的因子得到的平均值。 numpy.average()函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。 该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。

考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。

1
加权平均值 = (1*4+2*3+3*2+4*1)/(4+3+2+1)
1
2
3
4
5
6
7
8
9
import numpy as np
a = np.array([1,2,3,4])
print(np.mean(a))
# 2.5
weight = np.array([4,3,2,1])
print(np.average(a,weights=weight))
# 2.0
print(np.average(a,weights=weight,returned=True)) # 如果 returned 参数设为 true,则返回权重的和
# (2.0, 10.0)

在多维数组中,可以使用axis,指定用于计算的轴。

numpy.std()

标准差

numpy.var()

方差

NumPy排序、搜索和计数

Screen Shot 2018-06-24 at 8.37.20 PM

numpy.sort()

Screen Shot 2018-06-24 at 8.38.05 PM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
a = np.array([[3,7],[9,1]])
print(a)
# [[3 7]
# [9 1]]
print(np.sort(a))
# [[3 7]
# [1 9]]
print(np.sort(a,axis=0))
# [[3 1]
# [9 7]]
dt = np.dtype([('name', 'S10'),('age', int)])
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)
print(a)
# [(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]
print(np.sort(a,order='name'))
# [(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

numpy.argsort()

numpy.argsort()函数对输入数组沿给定轴执行间接排序,并使用指定排序类型返回数据的索引数组。 这个索引数组用于构造排序后的数组。

Screen Shot 2018-06-24 at 8.42.56 PM

numpy.lexsort()

用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。这里举一个应用场景:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取…… 这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。

1
2
3
4
5
6
7
8
9
import numpy as np
surnames = ('Hertz', 'Galilei', 'Hertz')
first_names = ('Heinrich', 'Galileo', 'Gustav')
ind = np.lexsort((first_names, surnames))
print(ind)
# [1 2 0]
print([surnames[i] + ", " + first_names[i] for i in ind])
# ['Galilei, Galileo', 'Hertz, Gustav', 'Hertz, Heinrich']

numpy.argmax()/.argmin()

这两个函数分别沿给定轴返回最大和最小元素的索引

numpy.nonzero()

返回输入数组中非零元素的索引。

numpy.where()

函数返回输入数组中满足给定条件的元素的索引

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
x = np.arange(9.).reshape(3,3)
print(x)
# [[0. 1. 2.]
# [3. 4. 5.]
# [6. 7. 8.]]
y = np.where(x>3)
print(y) #总共有5个,第一个array是横坐标,第二个array是纵坐标
# (array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
print(x[y])
# [4. 5. 6. 7. 8.]

numpy.extract()

返回满足任何条件的元素

1
2
3
4
5
6
7
8
9
import numpy as np
x = np.arange(9.).reshape(3,3)
print(x)
# [[0. 1. 2.]
# [3. 4. 5.]
# [6. 7. 8.]]
con = np.mod(x,2)==0
print(np.extract(con,x))
# [0. 2. 4. 6. 8.]

NumPy副本和视图

在执行函数时,其中一些返回输入数组的副本,而另一些返回视图。 当内容物理存储在另一个位置时,称为副本。 另一方面,如果提供了相同内存内容的不同视图,我们将其称为视图

赋值

简单的赋值不会创建数组对象的副本,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
a = np.arange(6)
print(a)
# [0 1 2 3 4 5]
b=a
b[0] = 111
print(a)
# [111 1 2 3 4 5]
b.shape=3,2
print(a)
# [[0 1]
# [2 3]
# [4 5]]

改变值,改变维度

浅复制

NumPy 拥有ndarray.view()方法,它是一个新的数组对象,并可查看原始数组的相同数据。 与前一种情况不同,新数组的维数更改不会更改原始数据的维数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
a = np.arange(6).reshape(2,3)
print(a)
# [[0 1 2]
# [3 4 5]]
b=a.view()
b[0] = 111
b.shape=3,2
print(b)
# [[111 111]
# [111 3]
# [ 4 5]]
print(a)
# [[111 111 111]
# [ 3 4 5]]

改变值,不改变维度

数组的切片也会创建视图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
a = np.array([[10,10], [2,3], [4,5]])
print(a)
# [[10 10]
# [ 2 3]
# [ 4 5]]
s = a[:2,:]
s[0]=-111
print(s)
# [[-111 -111]
# [ 2 3]]
print(a)
# [[-111 -111]
# [ 2 3]
# [ 4 5]]

深复制

ndarray.copy()函数创建一个深层副本。 它是数组及其数据的完整副本,不与原始数组共享。

b=a.copy():不改变数据,不改变维度

NumPy矩阵库

NumPy 包包含一个 Matrix库numpy.matlib。此模块的函数返回矩阵而不是返回ndarray对象。

numpy.matlib.empty()

Screen Shot 2018-06-25 at 12.11.39 PM

1
2
3
4
5
import numpy as np
import numpy.matlib
print(np.matlib.empty((2,3)))
# [[-1.72723371e-077 3.11109888e+231 1.48219694e-323]
# [ 0.00000000e+000 0.00000000e+000 4.17201348e-309]]

填充随机值

numpy.matlib.zeros()

以零填充矩阵

numpy.matlib.ones()

以一填充矩阵

numpy.matlib.eye()

Screen Shot 2018-06-26 at 9.35.31 AM

k:Index of the diagonal: 0 refers to the main diagonal, a positive value refers to an upper diagonal, and a negative value to a lower diagonal. k的值设置对角元素的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import numpy.matlib
print(np.matlib.eye(n = 3, M = 4, k=0,dtype = float))
# [[1. 0. 0. 0.]
# [0. 1. 0. 0.]
# [0. 0. 1. 0.]]
print(np.matlib.eye(n = 3, M = 4, k=1,dtype = float))
# [[0. 1. 0. 0.]
# [0. 0. 1. 0.]
# [0. 0. 0. 1.]]
print(np.matlib.eye(n = 3, M = 4, k=-1,dtype = float))
# [[0. 0. 0. 0.]
# [1. 0. 0. 0.]
# [0. 1. 0. 0.]]

numpy.matlib.identity()

返回给定大小的单位矩阵。单位矩阵是主对角线元素都为 1 的方阵。

1
2
3
4
5
6
7
8
import numpy as np
import numpy.matlib
print(np.matlib.identity(5))
# [[1. 0. 0. 0. 0.]
# [0. 1. 0. 0. 0.]
# [0. 0. 1. 0. 0.]
# [0. 0. 0. 1. 0.]
# [0. 0. 0. 0. 1.]]

numpy.matlib.rand()

返回给定大小的填充随机值的矩阵。

1
2
3
4
5
6
import numpy as np
import numpy.matlib
print(np.matlib.rand(3,3))
# [[0.72845877 0.93067466 0.57828842]
# [0.6117656 0.29529873 0.62999305]
# [0.76468178 0.18484781 0.96084426]]

矩阵与数组互换

np.asarray()和np.asmatrix()

NumPy线性代数

Screen Shot 2018-06-26 at 9.50.26 AM

wise_element乘法:

向量点积、点乘、內积、数量积:对应位相乘后求和,结果是一个标量

矩阵乘法:numpy.dot() 、numpy.matmul()

numpy.dot()

此函数返回两个数组的点积。 对于二维向量,其等效于矩阵乘法。 对于一维数组,它是向量的内积。 对于 N 维数组,它是a的最后一个轴上的和与b的倒数第二个轴的乘积。

1
2
3
4
5
6
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[11,12],[13,14]])
print(np.dot(a,b))
# [[37 40]
# [85 92]]

numpy.vdot()

此函数返回两个向量的点积。多维向量会被展开成一维。即 (1 X d) * (d X 1) = [1,1]

1
2
3
4
5
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[11,12],[13,14]])
print(np.vdot(a,b))
# 130

numpy.inner()

此函数返回一维数组的向量内积。 对于更高的维度,它返回最后一个轴上的和的乘积。

Screen Shot 2018-06-26 at 3.40.41 PM

numpy.matmul()

返回两个数组的矩阵乘积

1
2
3
4
5
6
import numpy as np
a = [[1,0],[0,1]]
b = [[4,1],[2,2]]
print(np.matmul(a,b))
# [[4 1]
# [2 2]]

numpy.linalg.det()

计算输入矩阵的行列式

numpy.linalg.solve()

给出了矩阵形式的线性方程的解。

Screen Shot 2018-06-26 at 3.49.39 PM

1
2
3
4
5
import numpy as np
A = [[1,1,1],[0,2,5],[2,5,-1]]
B = [6,-4,27]
print(np.linalg.solve(A,B))
# [ 5. 3. -2.]

numpy.linalg.inv()

求解逆矩阵

1
np.linalg.inv(x)

NumPy的IO文件操作

  • load()save()函数处理 numPy 二进制文件(带npy扩展名)
  • loadtxt()savetxt()函数处理正常的文本文件
1
2
3
4
5
import numpy as np
A = [[1,1,1],[0,2,5],[2,5,-1]]
a = np.array(A)
np.save('result',a) ##文件名是"result.npy"
b = np.load('result.npy')
1
2
3
4
import numpy as np
a = np.array([1,2,3,4,5])
np.savetxt('out.txt',a)
b = np.loadtxt('out.txt')