代码之家  ›  专栏  ›  技术社区  ›  Ivan Shelonik

np.nditer在子数组上迭代时不赋值

  •  0
  • Ivan Shelonik  · 技术社区  · 5 年前

    在分配内部方法期间,主数组不更新值 np.nditer公司

    array = np.arange(20)
    
    with np.nditer(array[np.nonzero(array)],
                   op_flags=['readwrite']) as it:
        for x in it:
            x[...] = 5
    array
    


    array[np.nonzero(array)] = 5
    array
    


    使用临时数组有一个解决方法。

    tmp_array = array[np.nonzero(array)]
    
    array = np.arange(20)
    
    with np.nditer(tmp_array,
                   op_flags=['readwrite']) as it:
        for x in it:
            x[...] = 5
    
    array[np.nonzero(array)] = tmp_array
    array
    

    数组([0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5])

    1. 为什么主数组在 np.nditer公司
    2. 有没有一种更方便的方法来解决子阵列分配的问题 np.nditer公司 发生?
    0 回复  |  直到 5 年前
        1
  •  1
  •   hpaulj    5 年前
    In [48]: arr = np.arange(20) 
        ...: with np.nditer(arr[np.nonzero(arr)], 
        ...:                op_flags=['readwrite']) as it: 
        ...:     for x in it: 
        ...:         x[...] = 5 
        ...: arr                                                                    
    Out[48]: 
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
           17, 18, 19])
    

    这不会改变 arr 因为它不是迭代的 阿里尔 . 相反,它在做:

    In [49]: arr = np.arange(20) 
        ...: arr1 = arr[np.nonzero(arr)] 
        ...: with np.nditer(arr1, 
        ...:                op_flags=['readwrite']) as it: 
        ...:     for x in it: 
        ...:         x[...] = 5 
        ...: arr1                                                                   
    Out[49]: array([5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5])
    In [50]: _.shape                                                                
    Out[50]: (19,)
    

    arr1 不是一个 view 阿里尔 ,它是selection,一个没有共享数据缓冲区的新数组。

    如果你想修改 阿里尔 ,你必须对它进行迭代,而不是复制。做测试,或任何花哨的事情,在循环内。

    In [51]: arr = np.arange(20) 
        ...: with np.nditer(arr, 
        ...:                op_flags=['readwrite']) as it: 
        ...:     for x in it: 
        ...:         if x > 0: 
        ...:             x[...] = 5 
        ...: arr                                                                    
    Out[51]: array([0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5])
    

    但你为什么要用 nditer

    array[np.nonzero(array)] = 5
    

    在这种情况下,任务 = 立即遵循高级索引,Python使用 array.__setitem__ 而不是 arr.__getitem__ .

    迭代一个切片,一个 看法

    In [52]: arr = np.arange(20) 
        ...: with np.nditer(arr[5:], 
        ...:                op_flags=['readwrite']) as it: 
        ...:     for x in it: 
        ...:         x[...] = 5 
        ...: arr                                                                    
    Out[52]: array([0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5])