Halo NumPy

NumPy是一个功能强大的Python库,用于对向量和矩阵进行计算。它提供了大量的库函数,可以帮助程序员轻松地进行数值运算。它是一个运算速度非常快的数学库,它的许多底层函数是用C语言编写的。
广泛应用于以下领域:

  • 机器学习
  • 图像处理与计算机图形学
  • 数学
  • 数据分析、数据挖掘

1. NumPy的安装

安装方法:
使用pip安装。在Windows系统中的cmd里,输入以下命令:pip install numpy

2. Numpy的数组

NumPy的核心即是对数组进行运算。数组在这里称之为ndarray。NumPy数组可以看成是一个相同类型的数值组成的格网。数组的维数(dimensions)称为数组的秩(rank)。数组的形状(shape)是一个包含各维大小的元组。

2.1 定义数组

array()函数:
创建数组最基本的方法是array()函数,可以给它传递任意序列。

numpy.array(object, [dtype=None, copy=True, order='K', subok=False, ndmin=0])
创建一个新的数组。

关于order参数的详细说明:
order参数的'C'和'F'是NumPy中数组元素存储区域的两种排列格式,即C语言格式和Fortran语言格式。
创建一个3×3的2维数组:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32)
数组a在数据存储区域(内存中)中的存储方式(默认order="C",其中一个格子是4bytes):
|1|2|3|4|5|6|7|8|9|
在C语言中当第一维数组也就是第0轴的下标增加1时,元素在内存中的地址增加3个元素的字节数,在此例中也就是12bytes,从1的地址增加12bytes到4的地址。
若以F order创建数组:
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32, order="F")
数组b在内存中的数据存储区域中的存储方式:
|1|4|7|2|5|8|3|6|9|
在Fortran语言中,第一维也就是第0轴下标增加1时,元素的地址增加一个元素字节数,在此例子中也就是4 bytes,从1的地址增加4bytes到4的地址。
如果order参数是'A',则返回的数组可能是'C' order也可能是'F' order,甚至是非连续形式'K'。一般不用该参数。
如果order参数是'K',则数组中的元素为元素在内存中的出现顺序。一般不用该参数。

arrange()函数:
返回给定区间内均匀间隔的值。

numpy.arange([start=0, ]stop, [step=1, ]dtype=None)
创建一个数组。数组的值在区间[start, stop)内,相隔step。

linspace()函数:
返回指定区间上均匀间隔的数字。

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
返回区间[start,stop]上均匀间隔的数字。可以选择性地排除该区间的端点stop,如果endpoint = True, stop是最后一个采样点,否则stop不被数组包含在内。endpoint默认是True。

full()函数
返回由指定值填充的指定形状和数据类型的数组。

numpy.full(shape, fill_value, dtype=None, order='C')

eye()函数
返回一个指定形状的单位矩阵。

numpy.eye(N, M=None, k=0, dtype=<class 'float'>, order='C')

zeros()函数:
创建元素都为0的数组。

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

ones()函数:
创建元素都为1的数组。用法同上。

numpy.ones(shape, dtype=None, order='C')

random.random()函数:
返回一个随机浮点值数组,随机值大小在[0.0,1.0)之间。

numpy.random.random(size=None)
size是可选参数,用来定义返回值的形状,默认值是None。当它是整型或整型的元组时,返回值是size形状的随机浮点值数组;当它是None时,返回值是单个随机浮点值。

  • 例1 创建一维数组
    给array传递一个列表,创建了一个一维数组。
import numpy  as np
my_array = np.array([1,2,3,4,5])
print(type(a))//输出:"<class 'numpy.ndarray'>"
print(my_array)//输出:[1 2 3 4 5]

my_new_array = np.zeros((5))//创建包含5个0元素的数组
print(my_new_array)//输出:[0. 0. 0. 0. 0.]

rnd_arr = np.random.random(5)
print(rnd_arr)//输出:[0.28355009 0.11279515 0.2376676  0.00790682 0.70743957]
  • 例2 用更多方式创建一维数组
import numpy  as np
a = np.array([0, 1, 2, 3, 4])
b = np.array((0, 1, 2, 3, 4))
c = np.arange(5)
d = np.linspace(0, 2*np.pi, 5)

print(a) //输出:[0 1 2 3 4]
print(b) //输出:[0 1 2 3 4]
print(c) //输出:[0 1 2 3 4]
print(d) //输出:[ 0.  1.57079633  3.14159265  4.71238898  6.28318531]
print(a[3]) //输出:3
  • 例3 创建多维数组

(1)使用zeros()、ones()等

import numpy  as np
d2_arr = np.zeros((2,3))//创建2行3列的二维数组
print(d2_arr[0][1])//输出:0.0

full_array = np.full((2,2), 7)  //创建2行2列的二维数组
print(full_array)               // 输出:[[ 7.  7.]
                                //      [ 7.  7.]]

d = np.eye(2)         //创建单位矩阵
print(d)              // 输出:[[ 1.  0.]
                      //       [ 0.  1.]]

(2)使用已有列表创建数组。为了创建一个二维数组,需传递一个列表的列表(或一个序列的序列)给array函数。若想要一个三维数组,需传递一个列表的列表的列表,以此类推。

import numpy  as np
my_array = np.array([[4,5],[6,1]])
print(my_array[0][1])//输出:5
print(my_array[0,0], my_array[0,1])//输出:4 5
print(my_array.shape)//输出:(2,2)
a = np.array([[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]])

print(a[2,4]) //输出:25

2.2 数组的属性

NumPy为数组ndarray提供了很多属性信息。

“dtype”是数组中数据的类型。
“size”是指数组中元素的个数。
数组的形状“shape”是指它的行列数,shape的返回值是一个元组,里面每个数字表示每一维的长度。
“itemsize”是每个项占用的字节数。一个int32有32位,即4个字节。
“ndim”是数组的维数。
“nbytes”是数组中所有数据消耗掉的字节数。需注意这不是数组的开销,数组占用的实际空间会稍微大一点。

  • 例1 常用属性
import numpy  as np
a = np.array([[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]])

print(type(a)) //输出:<class 'numpy.ndarray'>
print(a.dtype) //输出:int32
print(a.size) //输出:25
print(a.shape) //输出:(5, 5)
print(a.itemsize) //输出:4
print(a.ndim) //输出:2
print(a.nbytes) //输出:100
  • 例2 shape属性
    shape属性返回的是一个包含每一维长度的元组。很容易对一维数组产生误解,认为一维数组的shpae是“(1,元素个数 n)”这种样式,但实际上由于它是一维的,所以返回的元组只会包含一个元素,即这种样式:“(元组个数 n,)”,只包含一个数字,表示该数组元素的个数。另外需要说明的是:“(1,元素个数 n)”这种样式是二维数组才具有的,它表示该二维数组只有1行且该行有 n 个元素。
import numpy as np
x = np.arange(5)
y = np.arange(10)
y = np.reshape(y,(2,5))
z = np.reshape(x,(1,5))
print(x)//输出:[0 1 2 3 4]
print(y)//输出:[[0 1 2 3 4]
           //   [5 6 7 8 9]]
print(z)//输出:[[0 1 2 3 4]]
print(x.shape)//输出:(5,)
print(y.shape)//输出:(2, 5)
print(z.shape)//输出:(1, 5)

2.3 数组的切片

多维数组使用逗号分隔的行列号来切片,行列号从0起始。

  • 例1 取行或列
import numpy  as np
my_array = np.array([[4,5],[6,1]])
my_array_column = my_array[:,1]//取第二列
print(my_array_column)//输出:[5 1]
my_array_line = my_array[1,:]//取第二行
print(my_array_line)//输出:[6 1]
my_array_line = my_array[0]//取第一行
my_array_line = my_array[1]//取第二行
  • 例2 切片
import numpy  as np
a = np.array([[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]])

print(a[0, 1:4]) //输出:[12 13 14]
print(a[1:4, 0]) //输出:[16 21 26]
print(a[::2,::2]) //输出:[[11 13 15]
                  //      [21 23 25]
                  //      [31 33 35]]
print(a[:, 1]) //[12 17 22 27 32]

数组a的切片按下图进行工作。


  • 例3 花式索引
    该索引方法可以根据指定的索引获取特定元素。
import numpy  as np
a = np.arange(0, 100, 10)
indices = [1, 5, -1]
b = a[indices]
print(a) //输出:[ 0 10 20 30 40 50 60 70 80 90]
print(b) //输出:[10 50 90]
c = a.reshape((2,5))
indices = ((0,1),(1,2))
d = c[indices]
print(d)//输出:[10,70]
  • 例4 布尔屏蔽
    该索引方法可以根据指定的条件来获取数组中的元素。
import numpy  as np
a = np.linspace(0, 2 * np.pi, 50)
b = np.sin(a)

mask = b >= 0//生成一个True、False矩阵。b[i]>=0的位置为True,否则为False。
print(mask)
print(a[mask])
print(b[mask])

mask = (b >= 0) & (a <= np.pi / 2)//生成一个True、False矩阵。b[i]>=0 且 a[i]<=np.pi/2 的位置为True,否则为False。
print(mask)
print(a[mask])
print(b[mask])

  • 例5 缺省索引
import numpy  as np
a = np.arange(0, 100, 10)
b = a[:5]//缺省索引:获取前5个元素
c = a[a >= 50]//布尔屏蔽
print(b) //输出:[ 0 10 20 30 40]
print(c) //输出:[50 60 70 80 90]
  • 例6 可以修改Numpy数组的元素
import numpy  as np
my_array = np.array([1,2,3,4,5])
my_array[0] = -1//修改值为-1
print(my_array[0])//输出:-1,而不是1了

  • 例7 Where 函数
    where() 函数是根据条件返回数组中的值的有效方法。只需要把条件传递给它,它就会返回一个满足条件为真的元组或数组。

numpy.where(condition[, x, y])
condition是布尔型数组。x,y是数组类型,可选项。where的返回值分两种情况:
(1)指定了x与y
  当condition里的元素为True时,返回的数组里包含 x 对应位置的元素,否则包含 y 对应位置的元素。
(2)只有condition参数
  返回的是索引值元组,元组里包含的是condition里True元素的索引值。

a = np.arange(0, 100, 10)
b = np.where(a < 50) 
c = np.where(a >= 50)[0]
print(b) //输出:(array([0, 1, 2, 3, 4]),)
print(c) //输出:[5 6 7 8 9]

d = np.where([[True, False], [True, True]],
...          [[1, 2], [3, 4]],
...          [[9, 8], [7, 6]])
print(d)//输出:[[1 8]
        //       [3 4]]

e = np.where([[0, 1], [1, 0]])
print(e)//输出:(array([0, 1],dtype=int64), array([1, 0],dtype=int64))

x = np.arange(9.).reshape(3, 3)
print(np.where( x > 5 ))//输出:(array([2, 2, 2],dtype=int64), array([0, 1, 2],dtype=int64))
print(x[np.where( x > 3.0 )] )//输出:[4 5 6 7 8]
print(np.where(x < 5, x, -1))//输出:[[ 0 1 2]
                            //       [ 3  4 -1]
                            //       [-1 -1 -1]]     

2.4 数组操作

(1)reshape函数
reshape()函数
对数组的维度进行调整。

numpy.reshape(a, newshape, order='C')
在不改变数据的情况下,给数组定义新的形状。

import numpy as np 
a = np.arange(25)
a = a.reshape((5, 5))
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 24]]

(2)加减乘除

import numpy as np 
a = np.array([[1.0, 2.0], [3.0, 4.0]]) 
b = np.array([[5.0, 6.0], [7.0, 8.0]]) 
sum = a + b 
difference = a - b 
product = a * b 
quotient = a / b 
print("Sum = \n", sum)
print("Difference = \n", difference)
print("Product = \n", product)
print("Quotient = \n", quotient)

输出的结果:

Sum = [[ 6. 8.] [10. 12.]]
Difference = [[-4. -4.] [-4. -4.]]
Product = [[ 5. 12.] [21. 32.]]
Quotient = [[0.2 0.33333333] [0.42857143 0.5 ]]

(3)矩阵乘法

matrix_product = a.dot(b) 
print("Matrix Product = ", matrix_product)

输出将是:

[[19. 22.]
[43. 50.]]

(4)逻辑运算

print(a<b)
print(a>b)

输出将是:

[[True True]
 [True True]]
[[False False]
 [False False]]

(5)其他运算符

a = np.arange(10)
print(a.sum()) //输出:45
print(a.min()) //输出:0
print(a.max()) //输出:9
print(a.cumsum()) //输出:[ 0  1  3  6 10 15 21 28 36 45]

a.cumsum()的结果是a中的当前元素与该元素前的所有元素之和。

参考文献

[1]理解NumPy
[2]NumPy简单入门教程
[3]numpy中 C order与F order的区别是什么?
[4]NumPy v1.15 Manual
[5]python 里 np.array 的shape ( ,)与( ,1)的区别
[6]
[7]
[8]
[9]
[10]
[11]
[12]怎么理解numpy的where()
[13]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容