将函数应用于多维数组的每个元素并返回具有相同结构的新数组

时间:2017-01-14 16:47:25

标签: python arrays list function python-3.x

我是Python的新手。如果问题太简单,请道歉。我有一个函数,它返回主像素周围像素的标准偏差,如*:

def sliding_window(arr, window_size):
    """ Construct a sliding window view of the array"""
    arr = np.asarray(arr)
    window_size = int(window_size)
    if arr.ndim != 2:
        raise ValueError("need 2-D input")
    if not (window_size > 0):
        raise ValueError("need a positive window size")
    shape = (arr.shape[0] - window_size + 1,
             arr.shape[1] - window_size + 1,
             window_size, window_size)
    if shape[0] <= 0:
        shape = (1, shape[1], arr.shape[0], shape[3])
    if shape[1] <= 0:
        shape = (shape[0], 1, shape[2], arr.shape[1])
    strides = (arr.shape[1]*arr.itemsize, arr.itemsize,
               arr.shape[1]*arr.itemsize, arr.itemsize)
    return as_strided(arr, shape=shape, strides=strides)

def std(arr, i, j, d):
    """Return d-th neighbors of cell (i, j)"""
    w = sliding_window(arr, 2*d+1)

    ix = np.clip(i - d, 0, w.shape[0]-1)
    jx = np.clip(j - d, 0, w.shape[1]-1)

    i0 = max(0, i - d - ix)
    j0 = max(0, j - d - jx)
    i1 = w.shape[2] - max(0, d - i + ix)
    j1 = w.shape[3] - max(0, d - j + jx)

    return nu.std(w[ix, jx][i0:i1,j0:j1].ravel())

现在我想将此函数应用于数组的每个元素,并获得具有相同结构的数组:

例如:

array = [[2,3,4,4], 
         [3,4,3,5], 
         [4,5,6,6], 
         [3,6,7,7]]


formula =  [[std(array, 0,0,2), std(array, 1,0,2),std(array, 2,0,2),std(array, 3,0,2)],
          [std(array, 0,1,2), std(array, 1,1,2),std(array, 2,1,2),std(array, 3,1,2)],
          [std(array, 0,2,2), std(array, 1,2,2),std(array, 2,2,2),std(array, 3,2,2)],
          [std(array, 0,3,2), std(array, 1,3,2),std(array, 2,3,2),std(array, 3,3,2)]] 



    result = [[0.70710678118654757, 0.9574271077563381, 1.1989578808281798, 1.0671873729054748], 
[0.68718427093627676, 1.1331154474650633, 1.4624940645653537, 1.4229164972072998], 
[0.8660254037844386, 1.1873172373979173, 1.5, 1.4409680388158819],
 [0.68718427093627676, 1.0657403385139377, 1.35400640077266, 1.2570787221094177]]

我试图制作一个循环。类似的东西:

For k, v in array[i][j]:
   sd(array, i,j, n)

但到目前为止,循环非常令人沮丧....我希望你能帮助我。

2 个答案:

答案 0 :(得分:1)

你可以用

完成
array = [[2,3,4,4],
        [3,4,3,5],
        [4,5,6,6],
        [3,6,7,7]]

print [[[std(array,x,i,2) for x in xrange(len(array[i]))] for i in xrange(len(array))]]

# Result

[[[0.70710678118654757, 0.9574271077563381, 1.1989578808281798, 1.0671873729054748], [0.68718427093627676, 1.1331154474650633, 1.4624940645653537, 1.4229164972072998], [0.8660254037844386, 1.1873172373979173, 1.5, 1.4409680388158819], [0.68718427093627676, 1.0657403385139377, 1.35400640077266, 1.2570787221094177]]]

答案 1 :(得分:1)

看起来你可以使用scipy函数&#39; ndimage.generic_filter&#39;。

我们给它一个足迹(你的window_size),并将一个函数(np.nanstd)映射到每个项目的1d数组中,该数组在该足迹中匹配。

因为我们不得不担心边框,我们可以使用np.nanstd,并使用nans(cval = np.nan)填充数组。

import numpy as np
import scipy.ndimage as ndimage

results = np.empty(shape = (4,4), dtype = 'float') #to avoid type conversion
footprint = np.ones((2,2)) #change for your window size
#footprint[0,0] = 0 #not sure if this is intended

array = [[2,3,4,4], 
         [3,4,3,5], 
         [4,5,6,6], 
         [3,6,7,7]]

ndimage.generic_filter(array, np.nanstd, footprint=footprint, mode = 'constant', cval= np.nan, output = results, origin = -1)

results
array([[ 0.70710678,  0.5       ,  0.70710678,  0.5       ],
       [ 0.70710678,  1.11803399,  1.22474487,  0.5       ],
       [ 1.11803399,  0.70710678,  0.5       ,  0.5       ],
       [ 1.5       ,  0.5       ,  0.        ,  0.        ]])

结果与您的结果不同 - 不确定我的理解或足迹/原点/功能是否有问题。