#author("2023-09-26T19:37:29+08:00","default:Admin","Admin")
#author("2023-09-26T19:38:55+08:00","default:Admin","Admin")
[[Python]]

&color(red){※This article is based on Python 3.7.3};

#contents

* 章节数据准备 [#m0ea02e9]
此章节后面a的值为下方的初始化值。

#codeprettify{{
>>> import numpy as np
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])
}}

* 基本属性 [#i25dd598]

#codeprettify{{
>>> a.shape #(2, 3),返回一个元组,表示每个维度的大小。ndarray对象的尺度,对于矩阵,n行m列
>>> a.shape = (2,3) #shape属性是可写的,这个方法与a.reshape(2,3)效果一样。
>>> a.size #6,ndarray对象元素的个数,相当于.shape中n*m的值
>>> a.ndim #2 秩,即轴的数量或维度的数量
>>> a.itemsize #8 ndarray对象中每个元素的大小,以字节为单位
>>> a.dtype #dtype('int64')ndarray对象的元素类型
>>> a.itemsize #8 ndarray对象中每个元素的大小,以字节为单位
>>> a.flags #ndarray对象的内存信息
  C_CONTIGUOUS : True #数组位于单一的、C 风格的连续区段内
  F_CONTIGUOUS : False #数组位于单一的、Fortran 风格的连续区段内
  OWNDATA : True #数组的内存从其它对象处借用
  WRITEABLE : True #数据区域可写入。 将它设置为flase会锁定数据,使其只读
  ALIGNED : True #数据和任何元素会为硬件适当对齐
  WRITEBACKIFCOPY : False #
  UPDATEIFCOPY : False #这个数组是另一数组的副本。当这个数组释放时,源数组会由这个数组中的元素更新
}}

** 最大最小值 [#q7e0b0f3]
#codeprettify{{
>>> a.max()#最大值
6
>>> a.min()#最小值
1
>>> a.max(axis = 0)# axis=0 行方向最大值,即获得每列的最大值,若axis=1,则取列方向最大值,即获得每行的最大值
array([4, 5, 6])
>>> a.min(axis = 1)
array([1, 4])
>>> a.argmax(axis=1)# 最大值元素所在的位置
array([2, 2])
}}

** 平均值 [#pdad0d87]

*** 平均值mean() [#se24393d]

获得矩阵中元素的平均值可以通过函数mean()。同样地,可以获得整个矩阵、行或列的平均值。
#codeprettify{{
>>> a.mean() #3.5 即所有元素的平均值。
>>> a.mean(axis = 0)#行方向均值,即每列的均值。
array([2.5, 3.5, 4.5])
}}

*** 加权平均值numpy.average() [#s0fa673d]

是由每个分量乘以反映其重要性的因子得到的平均值。 numpy.average()函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。 该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。比如数组[1,2,3,4]和相应的权重[4,3,2,1],则加权平均值 = (1*4+2*3+3*2+4*1)/(4+3+2+1)
#codeprettify{{
>>> np.average(a)#如果不指定权值,则和平均值mean()效果一样。
3.5
>>> np.average(a,weights = [[1,2,3],[3,2,1]])#返回加权平均值。
3.5
>>> np.average(a,weights = [[1,2,3],[3,2,1]],returned = True)#返回加权平均值和权重的和。
(3.5, 12.0)
}}

*** 中值numpy.median() [#ic362bc4]

中值定义为将数据样本由小到大排序,取最中间的那一个,如果中间的数字有两个,取它们的平均值。
#codeprettify{{
>>> np.median(a)#3.5
}}

* 数组操作 [#y56f2ae3]

** 遍历数组 [#v3477a40]

*** enumerate() 函数 [#s2d99ac0]

#codeprettify{{
array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for i, row in enumerate(array):
    for j, element in enumerate(row):
        print("array[{}][{}] = {}".format(i, j, element))

#结果
array[0][0] = 1
array[0][1] = 2
array[0][2] = 3
array[1][0] = 4
array[1][1] = 5
array[1][2] = 6
array[2][0] = 7
array[2][1] = 8
array[2][2] = 9
}}

*** nditer() [#i99b93ff]

函数nditer() 主要用于循环遍历整个数组,而无需为每个额外维度使用嵌套for循环。

#codeprettify{{
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
for x in np.nditer(array):
    print(x)

#结果:
1
2
3
4
5
6
7
8
9
}}
** 修改数据 [#l71fce51]

#codeprettify{{
#一维数组
a=np.arange(0,10,1)**2
>>>array([ 0,  1,  4,  9, 16, 25, 36, 49, 64, 81])

a[-1]=100 #单个赋值
>>>array([  0,   1,   4,   9,  16,  25,  36,  49,  64, 100])

a[1:4]=100 #批量赋值
>>>array([  0, 100, 100, 100,  16,  25,  36,  49,  64, 100])

b=[np.sqrt(np.abs(i)) for i in a] #通过a循环遍历赋值
print(b)
>>>[0.0, 10.0, 10.0, 10.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0]
}}


** np.append() [#mda0d15c]

&color(red){返回新数组,不影响原来的数组};

#codeprettify{{
>>> a = np.arange(8)
>>> a
array([1, 2, 3, 4, 5, 6, 7])

>>>np.append(a, 8)
array([1, 2, 3, 4, 5, 6, 7, 8])

>>>np.append(a, [9,10])
array([1, 2, 3, 4, 5, 6, 7, 9, 10])

>>> x
array([1, 2, 3, 4, 5, 6, 7])
}}

注意一维数组和多维数组追加的区别:

n维数组要保持维度,只能追加n维数组,不然报错;

多维数组追加一维数组后,会变成一维数组(axis=None,先展平)


** np.where [#m3e829e9]

np.where 函数是三元表达式,有下面两种用法

*** np.where(condition,x,y) [#x91dfa4c]

当where内有三个参数时,第一个参数表示条件,当条件成立时where方法返回x,当条件不成立时where返回y



*** np.where(condition) [#re680740]

当where内只有一个参数时,那个参数表示条件,当条件成立时,where返回的是每个符合condition条件元素的坐标,返回的是以元组的形式

返回的是坐标

#codeprettify{{
import numpy as np
 
a = np.array([2, 4, 6, 8, 10])
#一维矩阵
result_1 = np.where(a > 5)
print(result_1)
 
b = np.random.randn(4, 4)
#二维矩阵
print(b)
result_2 = np.where(b > 0)
print(result_2)
}}

结果
#codeprettify{{
Output from spyder call 'get_namespace_view':
(array([2, 3, 4], dtype=int64),)
[[-0.83362412 -2.23605027  0.15374728  0.70877121]
 [-0.30212209  0.56606258  0.95593288  1.03250978]
 [-0.85764257  1.48541971  0.73199465  1.66331547]
 [-0.22020036  0.46416537 -0.75622715  0.32649036]]
(array([0, 0, 1, 1, 1, 2, 2, 2, 3, 3], dtype=int64), array([2, 3, 1, 2, 3, 1, 2, 3, 1, 3], dtype=int64))
}}

*** 例程 [#ia7fb14d]

使用numpy.where在图片上提取某一位置的坐标,遍历所有点耗费太耗费时间了,通过nump.where获取图片的某一位置坐标

#codeprettify{{
import numpy as np

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

print(np.where(a==2))
}}

返回
 (array([0], dtype=int64), array([1], dtype=int64))就是第2行第1列

*** 对比 [#g34598aa]

下面的数组比较会报错,[[详细看这里>+python+numpy库#n19523aa]]

 if ele != (0,0):

应该写成这样

 if np.array_equal(ele, [0, 0]):




#codeprettify{{
array1 = np.array([1, 2, 3, 4, 5])
array2 = np.array([1, 2, 3, 4, 6])

result = np.array_equal(array1, array2)

print(result)
}}
* Troubleshooting [#ze01b877]

** operands could not be broadcast together with shapes [#h4b5aa53]

*** 形状不同 [#d0ceeb2a]

#codeprettify{{
a = np.array([[1,2], [3,4]])
b = np.array([10,20,30,40])
c = a+b
# ValueError: operands could not be broadcast together with shapes (2,2) (4,)
}}

错误原因:将一个长度为4的数组加到一个2 x 2的数组上显然是不合法的,因为这两个矩阵的形状不同。

改为
#codeprettify{{
b = np.array([10,20,30,40]).reshape(2,2)
c = a+b

#结果:
array([[11, 22],
       [33, 44]])
}}


*** 维数不同 [#m5959e40]

 ValueError: operands could not be broadcast together with shapes (3,2) (3,)

列的数量不同导致的

 a = a.reshape(3,1)

** The truth value of an array with more than one element is ambiguous [#n19523aa]

在使用Numpy时,可能会遇到以下错误:

 ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

这个错误主要是因为Numpy的布尔运算有些独特,有时候会与Python的布尔运算不同。

#hr();
コメント:
#comment_kcaptcha

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS