使用额外的缓冲区使用NumPy很容易地对此代码进行矢量化:
import numpy.random
def foo(a, b):
for k in xrange(n):
bk = b[k]
b[k] = a[k] - bk
a[k] += bk
n = 16
x = numpy.random.randn(n) # some arbitrary input array, this is just for example
y = numpy.random.randn(n) # some arbitrary input array, this is just for example
foo(x, y)
但有没有办法让NumPy这样做没有分配额外的数组/缓冲区?
我打算只在1个向量化操作中执行此操作(以便每个内存位置只写入一次),很抱歉没有提及。
答案 0 :(得分:2)
怎么样:
a += b
b *= -2
b += a
答案 1 :(得分:0)
这会起作用吗?
import numpy.random
def foo(a, b):
for k in xrange(n):
a[k], b[k] = (a[k] + b[k], a[k] - b[k])
n = 16
x = numpy.random.randn(n) # some arbitrary input array, this is just for example
y = numpy.random.randn(n) # some arbitrary input array, this is just for example
foo(x, y)
我不认为在单个矢量化操作中可以做你想要的事情,因为不能一次为多个变量赋值......但我认为用元组作弊会使它看起来像是可能的: ]
答案 2 :(得分:0)
向量化本质上意味着在编译代码中而不是在高级语言中执行循环。 Numpy有许多用C语言编写的函数,但我不认为这个特殊情况有一个...所以,滚动你自己 - 如果你可以在你的平台上使用Cython这是直截了当的:
import numpy as np
cimport numpy as np
def c_foo(np.ndarray[np.float_t, ndim=1] a, np.ndarray[np.float_t, ndim=1] b):
cdef int n = a.shape[0]
cdef int k
cdef float bk
for k in range(n): # not sure if Cython likes `range` or `xrange` better on Python 2
bk = b[k]
b[k] = a[k] - bk
a[k] += bk
(我没有检查是否因为我的系统上缺少编译器而起作用,但是Cython正确地从这段代码中创建了一个.c文件。)
这看起来像是在音频处理中通常用于分离两个单声道/差分信号中的立体声信号的操作。您可能很幸运,可以在scipy或音频处理库中找到现有的实现。
答案 3 :(得分:0)
这是一种仅在我们控制内存布局时才有效的方法。具体而言,x
和y
必须交错并float
:
xy = np.random.randn(4, 2)
x, y = xy.T
print(x, y)
print(x-y, x+y)
xyc = xy.view(np.complex)
xyc *= 1+1j
print(x, y)
示例输出:
[ 1.17611837 -0.51923153 -0.35347014 0.17090538] [ 0.76679875 0.49908488 0.55649176 1.01126514]
[ 0.40931962 -1.0183164 -0.9099619 -0.84035975] [ 1.94291712 -0.02014665 0.20302162 1.18217052]
[ 0.40931962 -1.0183164 -0.9099619 -0.84035975] [ 1.94291712 -0.02014665 0.20302162 1.18217052]