Python,numpy.array切片,用切片改变数组值

时间:2017-05-05 16:25:10

标签: python arrays numpy slice

我有一个数值积分的任务,其中我们用积分公式近似积分。我的问题是,任务需要我避免循环并使用矢量化变体,这将是一个切片?!

我有n个值的np.array对象,我必须使用特定的公式更改此数组的每个值。问题是这个数组在i点的值是在公式中用来改变位置的。用for循环很容易:

x = np.array([...])
for i in range(0,n):
   x[i]=f(x[i]+a)*b`

(a,b一些其他变量) 我怎么用切片做这个?我必须为数组的所有元素执行此操作,因此它将类似于:

x[:]=f(x[???]+a)*b

我如何从我的阵列中获得正确的位置到公式?像x [:]之类的切片指令只是贯穿整个对象。有没有办法以某种方式保存我目前的索引? 我试图搜索但没有找到任何东西。另一个问题是我甚至不知道如何正确地提出搜索请求......

1 个答案:

答案 0 :(得分:0)

你可能会混淆两个问题

  • 修改数组的所有元素
  • 计算数组所有元素的值

x = np.array([...])
for i in range(0,n):
   x[i]=f(x[i]+a)*b`

您逐个更改x的元素,并将它们逐个传递给f

x[:] = ...允许您同时更改x的所有元素,但源(等式的右侧)必须生成所有这些值。但通常你不需要分配值。而只是使用x = ...。它的速度和内存效率一样快。

在RHS上使用x[:]对您没有任何帮助。如果x是一个列表,则会复制该列表;如果x是一个数组,则返回一个view,一个具有相同值的数组。

关键问题是,f(...)函数接受了什么?如果它使用+*等操作以及np.sin等函数,则可以为其指定数组,并返回数组。

但如果它仅适用于标量(包括使用math.sin等函数),则必须为其添加标量,即x[i]

让我们尝试解开该评论(这可能会更好地作为对原始问题的修改)

我有一个必须在picies中削减的间隔。

x = np.linspace(start,end,pieceAmount)
function f
quadrature formula
b (weights or factors)
c (function values)
b1*f(x[i]+c1)+...+bn*f(x[i]+cn)

例如

In [1]: x = np.arange(5)
In [2]: b = np.arange(3)
In [6]: c = np.arange(4,7)*.1

我们可以通过广播为所有x[i]+cx执行c

In [7]: xc = x + c[:,None]
In [8]: xc
Out[8]: 
array([[ 0.4,  1.4,  2.4,  3.4,  4.4],
       [ 0.5,  1.5,  2.5,  3.5,  4.5],
       [ 0.6,  1.6,  2.6,  3.6,  4.6]])

如果f是一个类似np.sin的函数,它接受任何数组,我们可以将xc传递给它,返回一个大小相同的数组。

再次通过广播我们可以进行b[n]*f(x[i]+c[n])计算

In [9]: b[:,None]* np.sin(xc)
Out[9]: 
array([[ 0.        ,  0.        ,  0.        , -0.        , -0.        ],
       [ 0.47942554,  0.99749499,  0.59847214, -0.35078323, -0.97753012],
       [ 1.12928495,  1.99914721,  1.03100274, -0.88504089, -1.98738201]])

然后我们可以总结一下,找回一个像x一样的数组:

In [10]: np.sum(_, axis=0)
Out[10]: array([ 1.60871049,  2.99664219,  1.62947489, -1.23582411, -2.96491212])

这是点或矩阵产品:

In [11]: b.dot(np.sin(xc))
Out[11]: array([ 1.60871049,  2.99664219,  1.62947489, -1.23582411, -2.96491212])

正如我之前提到的,我们可以用

完成动作
x = b.dot(f(x+c[:,None])

像这样的简单表达式的关键是f取一个数组。