您的位置:首页 > 编程语言 > Python开发

CS231n,你还需要了解点Numpy

2019-01-13 19:06 246 查看

Numpy

提供多维数组对象及处理多维数组的方法

Numpy是Python中用来进行科学计算的一个核心库。

讲解点⬇

注意:numpy不是默认安装的,需要在cmd中输入下述代码来安装:

pip3 install numpy

数组-Arrays

不同于python中的列表,Numpy中的数组是一个网格,只能由相同类型的值组成,且只能由非负数进行索引。

维数即为数组的秩(rank)

数组的形状(shape)是一个整形元组,给定了数组在每个维度上的大小。

数组的创建-Array creation
#使用python列表或嵌套列表对Numpy数组进行初始化

import numpy as np

#使用python列表进行初始化,即rank为1
a = np.array([1, 2, 3])   # Create a rank 1 array
print(type(a))            # Prints "<class 'numpy.ndarray'>"
print(a.shape)            # Prints "(3,)"
print(a[0], a[1], a[2])   # Prints "1 2 3"
a[0] = 5                  # Change an element of the array
print(a)                  # Prints "[5, 2, 3]"

#使用python嵌套列表进行初始化,rank取决于列表的个数
b = np.array([[1,2,3],[4,5,6]])    # Create a rank 2 array
print(b.shape)                     # Prints "(2, 3)"
print(b[0, 0], b[0, 1], b[1, 0])   # Prints "1 2 4"

#.shape输出的按照行、列、三维···进行输出
#numpy内置的构建数组的函数

import numpy as np

a = np.zeros((2,2))   # 创建一个2×2的零矩阵
print(a)              # Prints "[[ 0  0]
#          [ 0  0]]"

b = np.ones((1,2))    # 创建一个1×2的全一矩阵
print(b)              # Prints "[[ 1  1]]"

c = np.full((2,2), 7)  # 创建一个全是7的2×2矩阵
print(c)               # Prints "[[ 7  7]
#          [ 7  7]]"

d = np.eye(2)         # 创建一个2×2的单位矩阵
print(d)              # Prints "[[ 1  0]
#          [ 0  1]]"

e = np.random.random
1d25c
((2,2))  # 创建一个2×2的随机矩阵(value: 0~1)
print(e)                     # Might print "[[ 0.91940167  0.08143941]
#               [ 0.68744134  0.87236687]]"
数组索引-Array indexing

由索引方法找到需要的值~

分片-Slicing

对数组的每个维度指定一个片索引

通过分片的两数组共享同一个数据(两数组指向共同的共享块)

分片时若混合整数索引与片索引将导致秩(rank)的降低

# 通过对连续的块进行操作
# 下标索引法
import numpy as np

# Create the following rank 2 array with shape (3, 4)
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

# Use slicing to pull out the subarray consisting of the first 2 rows
# and columns 1 and 2; b is the following array of shape (2, 2):
# [[2 3]
#  [6 7]]
b = a[:2, 1:3]   # 选取a数组的第0~1行和第1到2列的元素值

#修改通过分片的数组的一个会导致另一个也被修改
# A slice of an array is a view into the same data, so modifying it
# will modify the original array.
print(a[0, 1])   # Prints "2"
b[0, 0] = 77     # b[0, 0] is the same piece of data as a[0, 1]
print(a[0, 1])   # Prints "77"
#混合整数索引和片索引将降低数组的秩

import numpy as np

# Create the following rank 2 array with shape (3, 4)
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

# Two ways of accessing the data in the middle row of the array.
# Mixing integer indexing with slices yields an array of lower rank,
# while using only slices yields an array of the same rank as the
# original array:
row_r1 = a[1, :]    # Rank 1 view of the second row of a
row_r2 = a[1:2, :]  # Rank 2 view of the second row of a
print(row_r1, row_r1.shape)  # Prints "[5 6 7 8] (4,)"
print(row_r2, row_r2.shape)  # Prints "[[5 6 7 8]] (1, 4)"

# We can make the same distinction when accessing columns of an array:
col_r1 = a[:, 1]
col_r2 = a[:, 1:2]
print(col_r1, col_r1.shape)  # Prints "[ 2  6 10] (3,)"
print(col_r2, col_r2.shape)  # Prints "[[ 2]
#          [ 6]
#          [10]] (3, 1)"
整数数组下标索引-Integer array indexing

由下标直接使用另一个数组的数据来构造新数组,这俩数组间的数据完全独立。

# 直接从所需元素在数组中的位置(下标)得到其内容

import numpy as np

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

# An example of integer array indexing.
# The returned array will have shape (3,) and
print(a[[0, 1, 2], [0, 1, 0]])  # Prints "[1 4 5]"

# The above example of integer array indexing is equivalent to this:
print(np.array([a[0, 0], a[1, 1], a[2, 0]]))  # Prints "[1 4 5]"

# When using integer array indexing, you can reuse the same
# element from the source array:
print(a[[0, 0], [1, 1]])  # Prints "[2 2]"

# Equivalent to the previous integer array indexing example
print(np.array([a[0, 1], a[0, 1]]))  # Prints "[2 2]"
#由另一个数组中的元素内容(内容是下标索引)进行选择。

import numpy as np

# Create a new array from which we will select elements
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])

print(a)  # prints "array([[ 1,  2,  3],
#                [ 4,  5,  6],
#                [ 7,  8,  9],
#                [10, 11, 12]])"

# Create an array of indices
b = np.array([0, 2, 0, 1])

# Select one element from each row of a using the indices in b
print(a[np.arange(4), b])  # Prints "[ 1  6  7 11]"

# Mutate one element from each row of a using the indices in b
a[np.arange(4), b] += 10

print(a)  # prints "array([[11,  2,  3],
#                [ 4,  5, 16],
#                [17,  8,  9],
#                [10, 21, 12]])
布尔数组索引-Boolean array indexing

多用于选择满足某些条件的数组元素

# 筛选出大于2的数组元素

import numpy as np

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

bool_idx = (a > 2)   # Find the elements of a that are bigger than 2;
# this returns a numpy array of Booleans of the same
# shape as a, where each slot of bool_idx tells
# whether that element of a is > 2.

print(bool_idx)      # Prints "[[False False]
#          [ True  True]
#          [ True  True]]"

# We use boolean array indexing to construct a rank 1 array
# consisting of the elements of a corresponding to the True values
# of bool_idx
print(a[bool_idx])  # Prints "[3 4 5 6]"

# We can do all of the above in a single concise statement:
print(a[a > 2])     # Prints "[3 4 5 6]"
数组中数据类型-Datatypes

通常在数组的创建过程中,Numpy会尝试猜测数据类型来给定数据类型。但是在构造数组的函数同时可以增加一个可选的参数来显示规定该数组包含的数据类型–.array([],dtype=?)

数据类型只能从精度小的转化成精度大的。
如从int32 -> float32 ,而不能反过来。

# 查看数据类型和创建时声明类型

import numpy as np

x = np.array([1, 2])   # Let numpy choose the datatype
print(x.dtype)         # Might prints "int64" or "int32"

x = np.array([1.0, 2.0])   # Let numpy choose the datatype
print(x.dtype)             # Prints "float64"

x = np.array([1, 2], dtype=np.int64)   # Force a particular datatype
print(x.dtype)                         # Prints "int64"

数组运算-Array math

数组基本计算

运算法则不同于矩阵,只是基于元素的四则运算,而非矩阵

通过dot()函数来计算矩阵的乘法

值得一提的是,在Numpy中,数组的基本数学运算已经内置实现,可直接对数组对象进行使用。
且既可以作为操作符的重载,也可以作为Numpy模块函数使用。

#对数组直接进行四则运算

import numpy as np

x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)

# Elementwise sum; both produce the array
# [[ 6.0  8.0]
#  [10.0 12.0]]
print(x + y)
print(np.add(x, y))

# Elementwise difference; both produce the array
# [[-4.0 -4.0]
#  [-4.0 -4.0]]
print(x - y)
print(np.subtract(x, y))

# Elementwise product; both produce the array
# [[ 5.0 12.0]
#  [21.0 32.0]]
print(x * y)
print(np.multiply(x, y))

# Elementwise division; both produce the array
# [[ 0.2         0.33333333]
#  [ 0.42857143  0.5       ]]
print(x / y)
print(np.divide(x, y))

# Elementwise square root; produces the array
# [[ 1.          1.41421356]
#  [ 1.73205081  2.        ]]
print(np.sqrt(x))
#用dot()函数来计算矩阵的乘法

import numpy as np

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

v = np.array([9,10])
w = np.array([11, 12])

# Inner product of vectors; both produce 219
print(v.dot(w))
print(np.dot(v, w))

# Matrix / vector product; both produce the rank 1 array [29 67]
print(x.dot(v))
print(np.dot(x, v))

# Matrix / matrix product; both produce the rank 2 array
# [[19 22]
#  [43 50]]
print(x.dot(y))
print(np.dot(x, y))
# 用sum(x)函数来计算x数组的所有元素的和
# 用sum(x,axis=0)函数来计算x数组的每列元素的和
# 用sum(x,axis=1)函数来计算x数组的每行元素的和

import numpy as np

x = np.array([[1,2],[3,4]])

print(np.sum(x))  # Compute sum of all elements; prints "10"
print(np.sum(x, axis=0))  # Compute sum of each column; prints "[4 6]"
print(np.sum(x, axis=1))  # Compute sum of each row; prints "[3 7]"
转置矩阵–Transposed matrix

转置操作对秩为1的数组不起作用

转置矩阵作用不言而喻,而Numpy中进行这一装置操作很简单。如下:

#对数组进行装置操作

import numpy as np

x = np.array([[1,2], [3,4]])
print(x)    # Prints "[[1 2]
#          [3 4]]"
print(x.T)  # Prints "[[1 3]
#          [2 4]]"

# 验证对rank为1的数组转置无效
v = np.array([1,2,3])
print(v)    # Prints "[1 2 3]"
print(v.T)  # Prints "[1 2 3]"
广播机制–Broadcasting

用于Numpy计算不同的shape的数组时所使用的机制即为Broadcasting。

#广播机制的实现

import numpy as np

# We will add the vector v to each row of the matrix x,
# storing the result in the matrix y
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = np.empty_like(x)   # Create an empty matrix with the same shape as x

# Add the vector v to each row of the matrix x with an explicit loop
for i in range(4):
y[i, :] = x[i, :] + v

# Now y is the following
# [[ 2  2  4]
#  [ 5  5  7]
#  [ 8  8 10]
#  [11 11 13]]
print(y)

当计算shape数多的数组很大时,如此循环再加的效率很低,可考虑对shape小的数组先进行扩展–叠加,然后通过一次加法得到最终结果。

#叠加多个副本的实现方法

import numpy as np

# We will add the vector v to each row of the matrix x,
# storing the result in the matrix y
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
vv = np.tile(v, (4, 1))   # Stack 4 copies of v on top of each other,copies 1 time
print(vv)                 # Prints "[[1 0 1]
#          [1 0 1]
#          [1 0 1]
#          [1 0 1]]"
y = x + vv  # Add x and vv elementwise
print(y)  # Prints "[[ 2  2  4
#          [ 5  5  7]
#          [ 8  8 10]
#          [11 11 13]]"

其实就如开头那个图,Numpy中可直接对不同shape的进行运算

#直接加法运算

import numpy as np

# We will add the vector v to each row of the matrix x,
# storing the result in the matrix y
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = x + v  # Add v to each row of x using broadcasting
print(y)  # Prints "[[ 2  2  4]
#          [ 5  5  7]
#          [ 8  8 10]
#          [11 11 13]]"

详细Numpy操作请访问 Numpy参考文档

上述示例代码均来自 CS231n-Python Numpy Tutorial

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: