import numpy as np
# 建立数组
# my_array = np.array([1,2,3,4,5])
# print(my_array)
#
# # 打印数组形状
# print(my_array.shape)
# print(my_array[0])
# print(my_array[1])
#
# # 重新赋值
# my_array[0] = -1
# print(my_array)
#
# my_new_array = np.zeros((5))
# print(my_new_array)
# [0. 0. 0. 0. 0.]
# my_array = np.ones(5)
# print(my_array)
# [1. 1. 1. 1. 1.]
# random array
# my_random_array = np.random.random((5))
# print(my_random_array)
#[0.09524675 0.8484897 0.69566609 0.21228995 0.63905217]
# 创建二维数组
# my_2d_array = np.zeros((2,3))
# print(my_2d_array)
# [[0. 0. 0.]
# [0. 0. 0.]]
# my_2d_array_new = np.ones((2,4))
# print(my_2d_array_new)
# # [[1. 1. 1. 1.]
# # [1. 1. 1. 1.]]
#
# # 索引
# myarray = np.array([[4,5],[6,1]])
# # 5
#
# # 取第二列
# myarray_column_2 = myarray[:,1]
# print(myarray_column_2)
# [5 1]
# 矩阵的加减乘除
# 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)
#
# [[ 6. 8.]
# [10. 12.]]
# print(difference)
# [[-4. -4.]
# [-4. -4.]]
# print(product)
# [[ 5. 12.]
# [21. 32.]]
# print(quotient)
# [[0.2 0.33333333]
# [0.42857143 0.5 ]]
# 以上矩阵乘法执行逐元素乘法而不是矩阵乘法。要执行矩阵乘法,可以执行以下操作。
# matrix_product = a.dot(b)
# print(matrix_product)
#
# print(np.dot(a,b))
# [[19. 22.]
# [43. 50.]]
# 一维数组
# a = np.array([0,1,2,3,4])
# print(a) #[0 1 2 3 4]
# b = np.array((0,1,2,3,4))
# print(b) #[0 1 2 3 4]
# c = np.arange(5)
# print(c) #[0 1 2 3 4]
# d = np.linspace(0,2*np.pi,5) #在指定的间隔内返回均匀间隔的数字。
# print(d) #[0. 1.57079633 3.14159265 4.71238898 6.28318531]
# ndarray = np.array([[1.0,2.0],[3.0,4.0]])
# print(ndarray.ndim) # 数组的轴(维度)的个数,rank
# 2
# print(ndarray.shape) #数组的维度 shape元组的长度就是rank
# (2, 2)
# print(ndarray.size) #数组元素的总数
# 4
# print(ndarray.dtype) #描述数组中元素类型的对象,可以使用标准的python类型创建或者指定dtype 另外np也提供自己的类型比如numpy.int32
# float64
# print(ndarray.itemsize) #数组中每个元素的字节大小
# 元素为 float64 类型的数组的 itemsize 为8(=64/8),而 complex32 类型的数组的 itemsize 为4(=32/8)。
# 它等于 ndarray.dtype.itemsize
# 8
# a = np.arange(15).reshape(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)
# print(a.dtype.name)
# 2
# int32
# print(a.itemsize)
# 4
# print(a.size) #15
# print(type(a)) #<class 'numpy.ndarray'>
#数组的创建
# a = np.array([2,3,4])
# print(a)
# print(a.dtype)
# b = np.array([1.2,3.5,5.1])
# print(b.dtype)
# [2 3 4]
# int32
# float64
# b = np.array([(1.5,2,3),(4,5,6)])
# print(b)
# # [[1.5 2. 3. ]
# # [4. 5. 6. ]]
#
# c = np.array([[1,2],[3,4]],dtype=complex)
# print(c)
# [[1.+0.j 2.+0.j]
# [3.+0.j 4.+0.j]]
# print(np.zeros((3,4)))
# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]]
# print(np.ones((2,3,4),dtype=np.int16))
# [[[1 1 1 1]
# [1 1 1 1]
# [1 1 1 1]]
#
# [[1 1 1 1]
# [1 1 1 1]
# [1 1 1 1]]]
# print(np.empty((2,3))) #np.empty()返回一个随机元素的矩阵,大小按照参数定义
# [[2.27e-322 0.00e+000 0.00e+000]
# [0.00e+000 0.00e+000 0.00e+000]]
# print(np.arange(10,30,5))
# [10 15 20 25]
# print(np.arange(0,2,0.3))
# [0. 0.3 0.6 0.9 1.2 1.5 1.8]
# print(np.linspace(0,2,9))
# [0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. ]
# print(np.linspace(0,2*np.pi,10))
# [0. 0.6981317 1.3962634 2.0943951 2.7925268 3.4906585
# 4.1887902 4.88692191 5.58505361 6.28318531]
# x = np.linspace(0,2*np.pi,100)
# f = np.sin(x)
# print(f)
#某些操作(例如 += *=)适用于修改现有数组,而不是创建新数组。
# a = np.ones((2,3),dtype=int)
# b = np.random.random((2,3))
#
# a *= 3
# print(a)
# # [[3 3 3]
# # [3 3 3]]
#
# b += a
# print(b)
# # [[3.03709483 3.96930446 3.51823164]
# # [3.29630817 3.29640868 3.9884277 ]]
# a += b
# TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int32') with casting rule 'same_kind'
# a = np.ones(3,dtype=np.int32)
#
# b = np.linspace(0,np.pi,3)
# # print(b.dtype.name)
# # float64
# c = a+b
# # print(c)
# # [1. 2.57079633 4.14159265]
# # print(c.dtype.name)
# # float64
#
# d = np.exp(c*1j) #1j表示i numpy.exp():返回e的幂次方,e是一个常数为2.71828
# print(d)
# # [ 0.54030231+0.84147098j -0.84147098+0.54030231j -0.54030231-0.84147098j]
# print(d.dtype.name)
# # complex128
# a = np.random.random((2,3))
# print(a)
# [[0.66613077 0.90484556 0.90366235]
# [0.30754789 0.99218275 0.37302029]]
# print(a.sum())
# 3.5856438821701633
# print(a.min())
# 0.06089753180019197
# print(a.max())
# 0.8921330962453111
#默认情况下,这些操作适用于数组,就好像它是数字列表一样,无论其形状如何。
# 但是,通过指定 axis 参数,你可以沿着数组的指定轴应用操作
# b = np.arange(12).reshape(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 = 0))
# [0 1 2 3] 每一列的最小值
# print(b.cumsum(axis=1))
# [[ 0 1 3 6]
# [ 4 9 15 22]
# [ 8 17 27 38]] 每一行的累积和
# 通用函数
# NumPy提供了常见的数学函数,如sin,cos和exp
# In NumPy, these are called “universal functions”( ufunc ).
# 在NumPy中,这些函数在数组上按元素级别操作,产生一个数组作为输出。
# b = np.arange(3)
# # print(b)
# # [0 1 2]
#
# # print(np.exp(b))
# # [1. 2.71828183 7.3890561 ]
#
# # print(np.sqrt(b))
# # [0. 1. 1.41421356]
#
# c = np.array([2.,-1.,4.])
# print(np.add(b,c)) #数组相加
# [2. 0. 6.]
# 索引、切片和迭代
# a = np.arange(10) ** 3
# # 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 #从开始到位置6 独占 将a[:6:2]取出来的元素设置为-1000
# print(a)
# [-1000 1 -1000 27 -1000 125 216 343 512 729]
# print(a[::-1])
# [729 512 343 216 125 64 27 8 1 0] #倒序排列
# for i in a:
# print(i ** (1 / 3.)) #每个元素开三次方
# 多维
# def f(x,y):
# return 10*x+y
# #
# b = np.fromfunction(f,(5,4),dtype=int)
# 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]) #0:5表示的是行 整体表示 b的第二列的每一行
# [ 1 11 21 31 41]
# print(b[:,1])
# [ 1 11 21 31 41] #跟前面的一样
# print(b[1:3,:])
# [[10 11 12 13]
# [20 21 22 23]]
# print(b[3:5,2:4])
# [[32 33]
# [42 43]]
# 取行或者列的时候的小技巧,想取哪一行或者哪一列,按照索引从0开始数,索引数就是第一个数
# 然后取几行或者几列在索引的基础上加上几就行了
# 当提供比轴数更少的索引时,缺失的索引被认为是一个完整切片 :
# print(b[-1]) #最后一行,等价于b[-1,:]
# [40 41 42 43]
# c = np.array( [[[ 0, 1, 2], # a 3D array (two stacked 2D arrays)
# [ 10, 12, 13]],
# [[100,101,102],
# [110,112,113]]])
# print(c.shape)
# (2, 2, 3)
# print(c[1,...]) #等价于c[1,:,:]或者c[1]
# print(c[...:2]) #等价于 c[:,:,2]
#迭代(Iterating) 多维数组是相对于第一个轴完成的:
# def f(x,y):
# return 10*x+y
# #
# b = np.fromfunction(f,(5,4),dtype=int)
# print(b)
# [[ 0 1 2 3]
# [10 11 12 13]
# [20 21 22 23]
# [30 31 32 33]
# [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]
# 但是,如果想要对数组中的每个元素执行操作,
# 可以使用 flat 属性,该属性是数组中所有元素的迭代器:
# for element in b.flat:
# print(element)
# 0
# 1
# 2
# 3
# 10
# 11
# ...
# 形状操作
# 更改数组的形状
# 一个数组具有由每个轴上的元素数量给出的形状:
# a = np.floor(10*np.random.random((3,4)))
# print(a)
# [[1. 3. 4. 4.]
# [5. 0. 5. 0.]
# [4. 3. 4. 5.]]
# np.floor 向下取整
# n = np.array([-1.7,-2.5,-0.2,0.6,1.2,2.7,11])
# floor = np.floor(n)
# print(floor)
# [-2. -3. -1. 0. 1. 2. 11.]
# print(a.shape)
# (3, 4)
# print(a.ravel()) #返回展平之后的数组
# [5. 7. 5. 5. 4. 3. 2. 6. 1. 4. 9. 8.]
# print(a.reshape(6,2))
# [[8. 7.]
# [7. 5.]
# [2. 5.]
# [8. 0.]
# [2. 6.]
# [7. 3.]]
# print(a.T)
# [[2. 2. 0.]
# [7. 0. 5.]
# [2. 2. 1.]
# [3. 7. 0.]]
# print(a.T.shape)
# (4, 3)
# print(a.shape)
# (3, 4)
# reshape 函数返回具有修改形状的参数,而 ndarray.resize 方法修改数组本身:
# print(a)
# [[1. 2. 5. 9.]
# [2. 3. 8. 0.]
# [9. 2. 7. 4.]]
# a.resize((2,6))
# print(a)
# [[1. 0. 8. 3. 6. 1.]
# [6. 1. 3. 8. 9. 5.]]
# 如果在reshape操作中将维度指定为-1,则会自动计算其他维度:
# print(a.reshape(3,-1))
# 将不同数组堆叠在一起
#几个数组可以沿不同的轴堆叠在一起。
# a = np.floor(10*np.random.random((2,2)))
# print(a)
# [[ 8., 8.],
# [ 0., 0.]]
# b = np.floor(10*np.random.random((2,2)))
# print(b)
# [[ 1., 8.],
# [ 0., 4.]]
# print(np.vstack((a,b)))
# array([[ 8., 8.],
# [ 0., 0.],
# [ 1., 8.],
# [ 0., 4.]])
# print(np.hstack((a,b)))
# array([[ 8., 8., 1., 8.],
# [ 0., 0., 0., 4.]])
# 函数 column_stack 将1D数组作为列叠加到2D数组中。它相当于仅用于二维数组的 hstack:
from numpy import newaxis
# f = np.column_stack((a,b))
# print(f)
# array([[ 8., 8., 1., 8.],
# [ 0., 0., 0., 4.]])
# a = np.array([4.,2.])
# b = np.array([3.,8.])
# f = np.column_stack((a,b))
# print(f)
# [[4. 3.]
# [2. 8.]]
# f = np.hstack((a,b))
# print(f)
# [4. 2. 3. 8.] 结果是不一样的
# print(a[:,newaxis])
# [[4.]
# [2.]]
#二维向量
# f = np.column_stack((a[:,newaxis],b[:,newaxis]))
# print(f)
# [[4. 3.]
# [2. 8.]]
# f = np.hstack((a[:,newaxis],b[:,newaxis]))
# print(f)
#
# [[4. 3.]
# [2. 8.]]
# 另一方面,对于任何输入数组,函数 row_stack 相当于 vstack。
# 一般来说,对于具有两个以上维度的数组,hstack 沿第二轴堆叠,vstack 沿第一轴堆叠,
# concatenate 允许一个可选参数,给出串接应该发生的轴。
# 在复杂情况下,r_ 和 c_ 可用于通过沿一个轴叠加数字来创建数组。它们允许使用范围字面量(“:”)
# f = np.r_[1:4,0,4]
# print(f)
# [1 2 3 0 4]
# f = np.r_[1:5,0,4]
# print(f)
# [1 2 3 4 0 4]
# f = np.r_[1:6,0,4]
# print(f)
# [1 2 3 4 5 0 4]
# 将一个数组分成几个较小的数组
# 使用 hsplit ,可以沿其水平轴拆分数组,
# 通过指定要返回的均匀划分的数组数量,
# 或通过指定要在其后进行划分的列:
# a = np.floor(10*np.random.random((2,12)))
# print(a)
# array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.],
# [ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]])
# f = np.hsplit(a,3)
# print(f)
#分成了三个小数组
# [array([[ 9., 5., 6., 3.],
# [ 1., 4., 9., 2.]]), array([[ 6., 8., 0., 7.],
# [ 2., 1., 0., 6.]]), array([[ 9., 7., 2., 7.],
# [ 2., 2., 4., 0.]])]
# 在第三列和第四列之后拆分
# f = np.hsplit(a,(3,4))
# print(f)
# [array([[ 9., 5., 6.],
# [ 1., 4., 9.]]), array([[ 3.],
# [ 2.]]), array([[ 6., 8., 0., 7., 9., 7., 2., 7.],
# [ 2., 1., 0., 6., 2., 2., 4., 0.]])]
# 在第三列和第四列之后拆分,分成三个数组,所以后面的数组自然组成一个数组。
# 复制和视图
# 简单赋值操作不会创建数组对象或者其数据的拷贝。
# a = np.arange(12)
# b = a #No create object is create
# print(b is a) #a and b are two names for the same ndarray object
# True
# b.shape = 3,4
# print(a.shape)
# (3, 4)
# python将可变对象作为引用传递,所以函数调用不会复制
# def f(x):
# print(id(x))
#
# print(id(a))
# print(id(b))
# 35173760
# 35173760
# id is a unique identifier of an object
# 视图或浅复制
# 不同的数组对象可以共享相同的数据。 view 方法创建一个新的数组对象,它查看相同的数据。
# c = a.view()
# print(c is a)
# False
# print(c.base is a) # c is a view of the data owned by a
# True
# print(c.flags.owndata)
# False
# c.shape = 2,6
# print(a.shape)
# (12,) #a 's shape doesn't change
# c[0,4] = 1234
# 改变c的值和形状,a的形状不会改变,但是a的值会变
# print(a)
# array([[ 0, 1, 2, 3],
# [1234, 5, 6, 7],
# [ 8, 9, 10, 11]])
# 对数组切片返回一个视图:
# s = a[:,1:3]
# s[:] = 10
# print(a)
# array([[ 0, 10, 10, 3],
# [1234, 10, 10, 7],
# [ 8, 10, 10, 11]])
# s[:]是s的视图,注意s[:] = 10和s=10的差异
# 深拷贝 d = a.copy() # print(d is a) # False #a new array object with data is created # print(d.base is a) #d doesn't share anything with a # False # d[0,0] = 9999 # print(a) # [[ 0, 10, 10, 3], # [1234, 10, 10, 7], # [ 8, 10, 10, 11]] # 这里列出了一些根据类别排列的有用的NumPy函数和方法名称。完整列表见Routines。 # 数组创建 # arange,array,copy,empty,empty_like,eye.fromfile,fromfunction, # identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r, zeros, zeros_like # 转换 # ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat #手法 # array_split, column_stack, concatenate, diagonal, dsplit, dstack, # hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack # 问题 # all, any, nonzero, where # # 顺序 # argmax, argmin, argsort, max, min, ptp, searchsorted, sort #操作 # choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum # 基本统计 # cov, mean, std, var # 基本线性代数 # cross, dot, outer, linalg.svd, vdot # Less 基础 #广播(Broadcasting)规则 # Broadcasting允许通用函数以有意义的方式处理具有不完全相同形状的输入。 # Broadcasting的第一个规则是,如果所有输入数组不具有相同数量的维度,则“1”将被重复地添加到较小数组的形状,直到所有数组具有相同数量的维度。 # Broadcasting的第二个规则确保沿着特定维度具有大小为1的数组表现得好像它们具有沿着该维度具有最大形状的数组的大小。假定数组元素的值沿“Broadcasting”数组的该维度相同。 # 在应用广播规则之后,所有阵列的大小必须匹配。更多细节可以在 Broadcasting 中找到。 # 花式索引和索引技巧 # NumPy提供了比常规Python序列更多的索引能力。正如我们前面看到的, # 除了通过整数和切片进行索引之外,还可以使用整数数组和布尔数组进行索引。 # 使用索引数组索引 # a = np.arange(12) ** 2 # print(a) # # [ 0 1 4 9 16 25 36 49 64 81 100 121] # i = np.array([1,1,3,8,5]) # # print(a[i]) # # [ 1 1 9 64 25] # j = np.array([[3,4],[9,7]]) # print(a[j]) # [[ 9 16] # [81 49]] # 当被索引的数组 a 是一个多维数组,单个索引数组指的是 a 的第一个维度。以下示例通过使用调色板将标签图像转换为彩色图像来作为举例。 # palette = np.array( [ [0,0,0], # black # # [255,0,0], # red # # [0,255,0], # green # # [0,0,255], # blue # # [255,255,255] ] ) # white # # # # image = np.array( [ [ 0, 1, 2, 0 ], # each value corresponds to a color in the palette # # [ 0, 3, 4, 0 ] ] ) # # # # print(palette[image]) # # [[[ 0 0 0] # # [255 0 0] # # [ 0 255 0] # # [ 0 0 0]] # # # # [[ 0 0 0] # # [ 0 0 255] # # [255 255 255] # # [ 0 0 0]]] # 我们也可以给出多个维度的索引。每个维度的索引数组必须具有相同的形状。 a = np.arange(12).reshape(3,4) # print(a) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] i = np.array([[0,1], [1,2]]) #单说a[i]取出来的数组是分别取第0行和第一行,第一行和第二行 # j = np.array([[2,1], [3,3]]) #对于a[i,j]来索引,先按照索引矩阵取原矩阵的元素就可以了,比如第一个元素是第0行第2列 # # #取 2 依次类推 # # # c1 = np.array([[2,1], # [1,1]]) # print(a[i]) # [[[ 0 1 2 3] # [ 4 5 6 7]] # # [[ 4 5 6 7] # [ 8 9 10 11]]] # print(a[i,c1]) # [[ 1 6] # [ 5 10]] # print(a[i,j]) # [[ 2 5] # [ 7 11]] # print(a[i,2]) # [[ 2 6] # [ 6 10]] # print(a[:,j]) # [[[ 2 1] # [ 3 3]] # # [[ 6 5] # [ 7 7]] # # [[10 9] # [11 11]]] # print(a[:,c1]) # [[[ 2 1] # [ 1 1]] # # [[ 6 5] # [ 5 5]] # # [[10 9] # [ 9 9]]] # 当然,我们可以把 i 和 j 放在一个序列中(比如一个列表),然后用列表进行索引。 # l = [i,j] # print(a[l]) # array([[ 2, 5], # [ 7, 11]]) # 然而,我们不能将 i 和 j 放入一个数组中,因为这个数组将被解释为索引第一个维度。 s = np.array([i,j]) # print(a[s]) # IndexError: index 3 is out of bounds for axis 0 with size 3 # print(a[tuple(s)]) # [[ 2 5] # [ 7 11]] # same as a[i,j] # 索引数组的另一个常见用途是搜索时间相关序列的最大值: time = np.linspace(0,145,5) data = np.sin(np.arange(20)).reshape(5,4) # print(time) # [ 0. 36.25 72.5 108.75 145. ] # print(data) # [[ 0. 0.84147098 0.90929743 0.14112001] # [-0.7568025 -0.95892427 -0.2794155 0.6569866 ] # [ 0.98935825 0.41211849 -0.54402111 -0.99999021] # [-0.53657292 0.42016704 0.99060736 0.65028784] # [-0.28790332 -0.96139749 -0.75098725 0.14987721]] # ind = data.argmax(axis=0) # 每个系列的最大值索引 # print(ind) # [2 0 3 1] # time_max = time[ind] # print(time_max) # [ 72.5 0. 108.75 36.25] # data_max = data[ind,range(data.shape[1])] #将最大值取出来 # print(data_max) # [0.98935825 0.84147098 0.99060736 0.6569866 ] # np.all(data_max==data_max(axis=0)) #矩阵比较 # True # 你还可以使用数组索引作为目标来赋值: a = np.arange(5) # print(a) # [0 1 2 3 4] # a[[1,3,4]] = 0 # print(a) # [0 0 2 0 0] # 然而,当索引列表包含重复时,赋值完成多次,留下最后一个值: # a = np.arange(5) # a[[0,0,2]] =[1,2,3] # print(a) # [2 1 3 3 4] # 这相当合理,但如果你想使用Python的 += 构造要小心,因为这可能得不到你想要的效果: # a = np.arange(5) # a[[0,0,2]] += 1 # print(a) # [1 1 3 3 4] # 即使0在索引列表中出现两次,第0个元素只会增加一次。这是因为Python要求“a + = 1”等同于“a = a + 1”。 # 使用布尔值作为数组索引 # 当我们用(整数)索引数组索引数组时,我们提供了要选择的索引列表。使用布尔值作为索引时,方法是不同的;我们明确地选择数组中的哪些元素我们想要的,哪些不是。 # 我们可以想到的布尔索引最自然的方式是使用与原始数组具有相同形状的布尔数组: # a = np.arange(12).reshape(3,4) # b = a > 4 # print(b) # [[False False False False] # [False True True True] # [ True True True True]] # print(a[b]) # [ 5 6 7 8 9 10 11] # 此属性在赋值时非常有用: # a[b] = 0 # print(a[b]) # [0 0 0 0 0 0 0] # 你可以查看以下示例,了解如何使用布尔索引生成 Mandelbrot 集的图像: # import matplotlib.pyplot as plt # def mandelbrot(h,w,maxit = 20): # """returns an imagine of the mandelbrot fractal of size(h,w).""" # y,x = np.ogrid[-1.4:1.4:h*1j,-2:0.8:w*1j] # c = x+y+1j # z = c # divtime = maxit + np.zeros(z.shape,dtype=int) # # for i in range(maxit): # z = z**2 +c # diverge = z*np.conj(z) > 2**2 # div_now = diverge & (divtime == maxit) # divtime[div_now] = i # z[diverge] = 2 # # # return divtime # # plt.show(mandelbrot(400,400)) # plt.show() # 第二种使用布尔索引的方法更类似于整数索引;对于数组的每个维度,我们给出一个一维布尔数组,选择我们想要的切片: # a = np.arange(12).reshape(3,4) # b1 = np.array([False,True,True]) # first dim selection # b2 = np.array([True,False,True,False]) # second dim selection # print(a[b1,:]) # [[ 4 5 6 7] # [ 8 9 10 11]] # print(a[b1]) # [[ 4 5 6 7] # [ 8 9 10 11]] # print(a[:,b2]) # [[ 0 2] # [ 4 6] # [ 8 10]] # print(a[b1,b2]) # [ 4 10] # 注意,1D布尔数组的长度必须与你要切片的维度(或轴)的长度一致。在前面的示例中, # b1 是rank为1的数组,其长度为3( a 中行的数量), b2 (长度4)适合于索引 a 的第二个rank(列)。 # ix_()函数 # 可以使用 ix_ 函数来组合不同的向量以获得每个n-uplet的结果。例如,如果要计算从向量a、b和c中的取得的所有三元组的所有a + b * c: # a = np.array([2,3,4,5]) # b = np.array([8,5,4]) # c = np.array([5,4,6,8,3]) # ax,bx,cx = np.ix_(a,b,c) # print(ax) # [[[2]] # # [[3]] # # [[4]] # # [[5]]] # print(bx) # [[[8] # [5] # [4]]] # print(cx) # [[[5 4 6 8 3]]] # print(ax.shape,bx.shape,cx.shape) # (4, 1, 1) (1, 3, 1) (1, 1, 5) # result = ax+bx*cx # print(result) # # [[[42 34 50 66 26] # [27 22 32 42 17] # [22 18 26 34 14]] # # [[43 35 51 67 27] # [28 23 33 43 18] # [23 19 27 35 15]] # # [[44 36 52 68 28] # [29 24 34 44 19] # [24 20 28 36 16]] # # [[45 37 53 69 29] # [30 25 35 45 20] # [25 21 29 37 17]]] # print(result[3,2,4]) # 17 # print(a[3]+b[2]*c[4]) # 17 # 你还可以如下实现reduce: # def ufunc__reduce(ufct,*vectors): # vs = np.ix_(*vectors) # r = ufct.identity # for v in vs: # r = ufct(r,v) # return r # # print(ufunc__reduce(np.add,a,b,c)) # [[[15 14 16 18 13] # [12 11 13 15 10] # [11 10 12 14 9]] # # [[16 15 17 19 14] # [13 12 14 16 11] # [12 11 13 15 10]] # # [[17 16 18 20 15] # [14 13 15 17 12] # [13 12 14 16 11]] # # [[18 17 19 21 16] # [15 14 16 18 13] # [14 13 15 17 12]]] # 与正常的ufunc.reduce相比,这个版本的reduce的优点是它使用Broadcasting规则,以避免创建参数数组输出的大小乘以向量的数量。 # 线性代数 # 简单数组操作 # a = np.array([[1.0,2.0],[3.0,4.0]]) # print(a) # [[1. 2.] # [3. 4.]] # print(a.transpose()) #转置 # [[1. 3.] # [2. 4.]] # print(np.linalg.inv(a)) # [[-2. 1. ] # [ 1.5 -0.5]] # (1)np.linalg.inv():矩阵求逆 # (2)np.linalg.det():矩阵求行列式(标量) # u = np.eye(2) #生成对角矩阵 # print(u) # [[1. 0.] # [0. 1.]] # j = np.array([[0.0,-1.0],[1.0,0.0]]) # print(np.dot(j,j)) # [[-1. 0.] # [ 0. -1.]] # print(np.trace(u)) #矩阵的迹 # 2.0 # y = np.array([[5.],[7.]]) # print(np.linalg.solve(a,y)) #求解线性矩阵方程或线性标量方程组。 # [[-3.] # [ 4.]] # print(np.linalg.eig(j)) #计算矩阵的特征向量 # (array([0.69722436, 4.30277564]), array([[-0.60889368, -0.3983218 ], # [ 0.79325185, -0.91724574]]))