1D Numpy数组相当于压缩前一个,当前和后续元素

时间:2017-02-23 01:55:24

标签: python arrays numpy

我无法在其他地方找到答案。

对于1D 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)的值。

我错过了什么?

3 个答案:

答案 0 :(得分:0)

首先,您可能希望三个数组的长度相同。这意味着要么填充数组的末尾,要么循环8个元素而不是10个。这是后一种方法:

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

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

如果您坚持使用for循环进行处理而不是向量化该函数,则可以通过完全消除zip并使用单个2D数组来获得微小的改进:

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

答案 1 :(得分: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:])

请注意,这将为您带来便利,但不会为您提供便利。

答案 2 :(得分: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]