zl程序教程

您现在的位置是:首页 >  后端

当前栏目

numpy-切片,索引,广播,迭代

numpy索引迭代 切片 广播
2023-09-27 14:19:57 时间

切片与索引:

slice

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

import numpy as np

a = np.arange(10)
s = slice(2, 7, 2)
print(a[s])

从2到6,步长为2
如果不用slice,通过将由冒号分隔的切片参数(start:stop:step)直接提供给ndarray对象,也可以获得相同的结果。
例:

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

对单个元素进行切片:
就是直接引用下标

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

也适用于多维数组

import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
#   [[1 2 3]
#  [3 4 5]
#  [4 5 6]]
print(a)
# 对始于索引的元素进行切片
#
print ( '现在我们从索引 a[1:] 开始对数组切片')
#   [[3 4 5]
#  [4 5 6]]
print (a[1:])

高级索引:

如果一个ndarray是非元组序列,数据类型为整数或布尔值的ndarray,或者至少一个元素为序列对象的元组,我们就能够用它来索引ndarray。高级索引始终返回数据的副本。 与此相反,切片只提供了一个视图。

整数索引:

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

import numpy as np

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

该结果包括数组中(0,0),(1,1)和(2,0)位置处的元素。
获取了 4X3 数组中的每个角处的元素。 行索引是[0,0]和[3,3],而列索引是[0,2]和[0,2]。

import numpy as np

x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print('我们的数组是:')
print(x)
print('\n')
rows = np.array([[0, 0], [3, 3]])
cols = np.array([[0, 2], [0, 2]])
y = x[rows, cols]
print('这个数组的每个角处的元素是:')
print(y)
#   我们的数组是:
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]
# 
# 
# 这个数组的每个角处的元素是:
# [[ 0  2]
#  [ 9 11]]

布尔索引:

当结果对象是布尔运算(例如比较运算符)的结果时,将使用此类型的高级索引
例:大于 5 的元素会作为布尔索引的结果返回

import numpy as np

x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print ('我们的数组是:')
print(x)
print('\n')
# 现在我们会打印出大于 5 的元素
print('大于 5 的元素是:')
#   [ 6  7  8  9 10 11]
print(x[x > 5])

如何从数组中过滤掉非复数元素

import numpy as np

a = np.array([1, 2 + 6j, 5, 3.5 + 5j])
#   [2.0+6.j  3.5+5.j] 
print(a[np.iscomplex(a)])

广播:

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

import numpy as np

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])
c = a * b
#   [ 10  40  90 160]
print(c)

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

如果满足以下规则,可以进行广播:

ndim较小的数组会在前面追加一个长度为 1 的维度。

输出数组的每个维度的大小是输入数组该维度大小的最大值。

如果输入在每个维度中的大小与输出大小匹配,或其值正好为 1,则在计算中可它。

如果输入的某个维度大小为 1,则该维度中的第一个数据元素将用于该维度的所有计算。

如果上述规则产生有效结果,并且满足以下条件之一,那么数组被称为可广播的。

数组拥有相同形状。

数组拥有相同的维数,每个维度拥有相同长度,或者长度为 1。

数组拥有极少的维度,可以在其前面追加长度为 1 的维度,使上述条件成立。

import numpy as np

a = np.array([[0.0, 0.0, 0.0], [10.0, 10.0, 10.0], [20.0, 20.0, 20.0], [30.0, 30.0, 30.0]])
b = np.array([1.0, 2.0, 3.0])
print('第一个数组:')
print(a)
print('\n')
print('第二个数组:')
print(b)
print('\n')
print('第一个数组加第二个数组:')
print(a + b)
#   第一个数组:
# [[ 0.  0.  0.]
#  [10. 10. 10.]
#  [20. 20. 20.]
#  [30. 30. 30.]]
# 
# 
# 第二个数组:
# [1. 2. 3.]
# 
# 
# 第一个数组加第二个数组:
# [[ 1.  2.  3.]
#  [11. 12. 13.]
#  [21. 22. 23.]
#  [31. 32. 33.]]

数组上的迭代

import numpy as np

a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
print('原始数组是:')
print(a)
print('\n')
print('修改后的数组是:')
for x in np.nditer(a):
    print(x,end=' ')
#   原始数组是:
# [[ 0  5 10 15]
#  [20 25 30 35]
#  [40 45 50 55]]
# 
# 
# 修改后的数组是:
# 0 5 10 15 20 25 30 35 40 45 50 55 

其中的reshape(i,j).指的是,转化为i行j列

小记:这两天感觉有点懒散。。。