• Lesson10——NumPy 迭代数组


    NumPy 教程目录

    NumPy 迭代数组

      NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。

      迭代器最基本的任务的可以完成对数组元素的访问。

    Example:使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代。

    a = np.arange(6).reshape(2,3)
    print('原始数组是')
    print(a)
    print('迭代输出元素')
    for x in np.nditer(a):
        print(x,end=' ')
    #输出结果
    """
    原始数组是
    [[0 1 2]
     [3 4 5]]
    迭代输出元素
    0 1 2 3 4 5 
    """
    

    Example:

    a = np.arange(8).reshape(2,2,2)
    print('原始数组是')
    print(a)
    print('迭代输出元素')
    for x in np.nditer(a):
        print(x,end=' ')
    
    #输出结果
    """
    原始数组是
    [[[0 1]
      [2 3]]
    
     [[4 5]
      [6 7]]]
    迭代输出元素
    0 1 2 3 4 5 6 7 
    """
    

      以上实例不是使用标准 C 或者 Fortran 顺序,选择的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先(row-major order,或者说是 C-order)。

      这反映了默认情况下只需访问每个元素,而无需考虑其特定顺序。我们可以通过迭代上述数组的转置来看到这一点,并与以 C 顺序访问数组转置的 copy 方式做对比,如下实例:

    Example:

    a = np.arange(6).reshape(2,3)
    for x in np.nditer(a.T):
        print(x,end=' ')
    print()
    print(a.T.copy(order ='C'))
    for x in np.nditer(a.T.copy(order ='C')):
        print(x,end=' ')
    #输出结果
    """
    0 1 2 3 4 5 
    [[0 3]
     [1 4]
     [2 5]]
    0 3 1 4 2 5 
    """
    

      从上述例子可以看出, a a.T 的遍历顺序是一样的,也就是他们在内存中的存储顺序也是一样的,也就是他们在内存中的存储顺序也是一样的,但是出, a.T.copy(order='C') 的遍历结果是不同的,那是因为它和前两种的存储方式是不一样的,默认是按行访问。

    控制遍历顺序

    • for x in np.nditer(a, order='F'):Fortran order,即是列序优先;
    • for x in np.nditer(a.T, order='C'):C order,即是行序优先;

    Example:

    a = np.arange(0,60,5) 
    a = a.reshape(3,4)  
    print ('原始数组是:') 
    print (a) 
    print ('\n') 
    print ('原始数组的转置是:') 
    b = a.T 
    print (b) 
    print ('\n') 
    print ('以 C 风格顺序排序:') 
    c = b.copy(order='C')  
    print (c)
    for x in np.nditer(c):  
        print (x, end=", " )
    print  ('\n') 
    print  ('以 F 风格顺序排序:')
    c = b.copy(order='F')  
    print (c)
    for x in np.nditer(c):  
        print (x, end=", " )
    #输出结果
    """
    原始数组是:
    [[ 0  5 10 15]
     [20 25 30 35]
     [40 45 50 55]]
    
    原始数组的转置是:
    [[ 0 20 40]
     [ 5 25 45]
     [10 30 50]
     [15 35 55]]
    
    以 C 风格顺序排序:
    [[ 0 20 40]
     [ 5 25 45]
     [10 30 50]
     [15 35 55]]
    0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 
    
    以 F 风格顺序排序:
    [[ 0 20 40]
     [ 5 25 45]
     [10 30 50]
     [15 35 55]]
    0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 
    """
    

     可以通过显式设置,来强制 nditer 对象使用某种顺序:

    Example:

    a = np.arange(0,60,5) 
    a = a.reshape(3,4)  
    print ('原始数组是:')
    print (a)
    print ('\n')
    print ('以 C 风格顺序排序:')
    for x in np.nditer(a, order =  'C'):  
        print (x, end="  " )
    print ('\n')
    print ('以 F 风格顺序排序:')
    for x in np.nditer(a, order =  'F'):  
        print (x, end=" " )
    #输出结果
    """
    原始数组是:
    [[ 0  5 10 15]
     [20 25 30 35]
     [40 45 50 55]]
    
    以 C 风格顺序排序:
    0  5  10  15  20  25  30  35  40  45  50  55  
    
    以 F 风格顺序排序:
    0 20 40 5 25 45 10 30 50 15 35 55 
    """
    

    修改数组中元素的值

      nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。

    Example:

    x = np.arange(6).reshape((2,3))
    print('The original array is')
    print(x)
    for tmp in np.nditer(x,op_flags =['readwrite']):
        tmp[...] = 1
    print("The modified array is")
    print(x)
    #output result
    """
    The original array is
    [[0 1 2]
     [3 4 5]]
    The modified array is
    [[1 1 1]
     [1 1 1]]
    """
    

    使用外部循环

      nditer 类的构造器拥有 flags 参数,它可以接受下列值:

    参数 描述
    c_index 可以跟踪 C 顺序的索引
    f_index 可以跟踪 Fortran 顺序的索引
    multi_index 每次迭代可以跟踪一种索引类型
    external_loop 给出的值是具有多个值的一维数组,而不是零维数组

      在下面的实例中,迭代器遍历对应于每列,并组合为一维数组。

    Example:

    x = np.arange(9).reshape((3,3))
    print("The original array is ")
    print(x)
    print('The modified array is ')
    for x in np.nditer(x,flags=['external_loop'],order='F'):
        print(x)
    #output result
    """
    The original array is 
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    The modified array is 
    [0 3 6]
    [1 4 7]
    [2 5 8]
    """
    

    广播迭代

      如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。 假设数组 $ a $ 的维度为 \(3\times4\),数组 \(b\) 的维度为 \(1\times4\) ,则使用以下迭代器(数组 \(b\) 被广播到 \(a\) 的大小)。

    Example:

    a = np.arange(0,60,5) 
    a = a.reshape(3,4)  
    print  ('First array:')
    print (a)
    print  ('\n')
    print ('Second array:')
    b = np.array([1,  2,  3,  4], dtype =  int)  
    print (b)
    print ('\n')
    print ('The modified array :')
    for x,y in np.nditer([a,b]):  
        print ("%d:%d"  %  (x,y), end=", " )
    #output result
    """
    First array:
    [[ 0  5 10 15]
     [20 25 30 35]
     [40 45 50 55]]
    
    Second array:
    [1 2 3 4]
    
    The modified array :
    0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4, 
    """
    
  • 相关阅读:
    Codeforces Global Round 11
    2018-2019 ICPC, Asia Najing
    Codeforces Round #675 (Div. 2) ABCDE
    AtCoder Regular Contest 104 D(卡常)
    Navigator History Location
    键盘移动div
    键盘事件
    事件的传播
    事件的绑定
    事件的委派
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/15891986.html
Copyright © 2020-2023  润新知