我无法在其他地方找到答案。
对于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)的值。
我错过了什么?
答案 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]