2017-02-23 41 views
1

我一直无法在其他地方找到答案。1D Numpy阵列相当于先前,当前和以下元素的压缩

对于一维numpy的随机数组,例如a = np.random.rand(10),我想对每个包含它的每个相邻元素(即前一个和后一个元素)的元素执行一个操作。所以,像

write = [] 

for previous_item, current_item, next_item in zip(a,a[1::],a[2::]): 
    write += operation_on(previous_item, current_item, next_item) 

但是当我尝试用numpy的阵列上的那些片商要做到这一点,它告诉我,a[1::]等是浮动。是否有一个Numpy-Array等效于压缩数组中的相邻元素?

这里是什么,我不能去上班一个简单的版本:

from random import randint 
import math 
import numpy as np 

size = 3 

def logistic(x,b): 
    return b*x*(1-x) 

def scheme(l,c,r,strength,b): 
    print('neighborhood: ',l,c,r) 
    new_center = (1-strength)*logistic(c,b)+(strength/2)*(logistic(r,b) + logistic(l,b)) 
    return new_center 

def eSimple(c,l=None,r=None): 
    return c 

cml = np.random.rand(size**2) 

def evolve(cml, r): 
    # encode all 
    cml = np.vectorize(eSimple)(cml[:-2], cml[1:-1], cml[2:]) 
    cml = np.vectorize(scheme)(cml[:-2], cml[1:-1], cml[2:], 0.5, r) 

for r in np.arange(3.6, 4.0, 0.05): 
    evolve(cml,r) 
    print(cml) 

出于某种原因,尽管它正确生成的街区,cml仅仅是增加其值由一个非常小的(〜1E-6 )从每个步骤的初始随机值开始计算。

我错过了什么?

+0

若本只适用于一维numpy数组? –

+0

我试过你的代码,如果我为operation_on插入一些东西,它对我有用,虽然结果有点无聊(写入被强制为一个空数组,并且将一个标量添加到一个空数组并没有多大作用) –

+0

@ sphericalcowboy I don真的不介意 - 我只想要一种方法来做到这一点。我想使用一维Numpy数组,而不是一个列表,但就目前而言,我只能找出一种方法来完成列表。 –

回答

0

这样做的numpy方式将是

write = operation_on(a[:-2], a[1:-1], a[2:]) 

但这只适用于如果operation_on矢量化。例如,如果operation_on(x, y, z)返回x*x - np.sin(y) + np.exp(z)它将工作,因为单个操作都知道如何处理数组。

如果不是,您可以使用

write = np.vectorize(operation_on)(a[:-2], a[1:-1], a[2:]) 

注意,这将让你的方便,但numpy的不是速度。

+0

当我以这种方式运行时,即使函数I返回'r * x *(1-x)',而'r'是另一个参数,这些值似乎会增加一个令人难以置信的小数量,所以它似乎符合你的矢量化要求 –

+0

@JackLynch我认为你的函数需要3个参数? –

+0

我的不好 - 我的功能需要这三个,并且将中心元素应用于其他两个的“地图”(这就是我所描述的)。在这里,我只是编辑我的答案,在不知道你的'.encode'方法的情况下发布我的代码 –

0

首先,您可能希望三个数组的长度相同。这意味着要么填充所述阵列的端部,或遍历8个元素,而不是10。这里是后一种方法:

for p, c, n in zip(a[:-2], a[1:-1], a[2:]): 
    ... 

此语法将相同方式工作为一个列表或阵列。主要区别在于列表切片将返回副本,而数组切片是对同一底层缓冲区的视图。

如果你坚持使用for循环为你处理而不是向量化的功能,您可以消除拉链完全和使用一个二维数组得到边际改善:

b = np.stack((a[:-2], a[1:-1], a[2:]), -1) 
for p, c, n in b: 
    ... 
+0

如果我没有完全弄错,zip会将它的参数截断为最短的长度。 –

+0

@PaulPanzer。真正。我正在努力从这个混乱中获得一个2D数组,但意识到它没有帮助。 –

+0

此外,即使其他形式的作品,我认为你的风格更好。显式比隐式更好。 –

0

如果你开始元素1与元素-2结束,即只使用两个邻国(前一个和下一个元素)元素:

import numpy as np 


def operation(pre, cur, nex): 
    return pre + cur + nex # sum as an example operation 


a = np.random.randint(3, size=(10,)) # output easier to see using ints 
write = [] 

for pr, cr, nx in zip(a[:-2], a[1:-1], a[2:]): 
    write.append(operation(pr, cr, nx)) 

print(a) 
print(write) 

输出:

[0 2 2 0 0 1 0 1 1 1] 
[4, 4, 2, 1, 1, 2, 2, 3]