简体   繁体   English

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

[英]Python, numpy.array slicing, altering array values with slices

I have a Task for numerical integration in which we approximate integral with quadrature formula. 我有一个数值积分任务,其中我们用积分公式近似积分。 My problem is that the task needs me to avoid loops and use vectorized variant, which would be a slice?! 我的问题是任务需要我避免循环并使用矢量化变量,这将是片吗?

I have np.array object with n values and i have to alter each value of this array using a specific formula. 我有n个值的np.array对象,我必须使用特定的公式来更改此数组的每个值。 The problem is that the value of this array at point i ist used in the formula to alter the position in. With a for loop it would be easy: 问题在于公式中使用此数组在点i处的值来更改位置。使用for循环将很容易:

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

(a,b some othe variables) How do i do this with slices? (a,b一些其他变量)我该如何用切片呢? I Have to do this for all elements of the array so it would be something like: 我必须对数组的所有元素执行此操作,因此将类似于:

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

And how do i get the right position from my array in to the formula? 我如何从数组中获得正确的位置到公式中? A slicing instruction like x[:] just runs through my whole object. 像x [:]这样的切片指令仅遍历我的整个对象。 Is there a way to somehow save the index i am currently at? 有什么方法可以保存我当前所在的索引吗? I tried to search but found nothing. 我试图搜索但什么也没找到。 The other problem is that i do not even know how to properly put the search request... 另一个问题是我什至不知道如何正确放置搜索请求...

You may be confusing two issues 您可能会混淆两个问题

  • modifying all elements of an array 修改数组的所有元素
  • calculating values for all elements of an array 计算数组所有元素的值

In

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

you change elements of x one by one, and also pass them one by one to f . 您将x元素一一更改,并将它们一一传递给f

x[:] = ... lets you change all elements of x at once, but the source (the right hand side of the equation) has to generate all those values. x[:] = ...使您可以立即更改x所有元素,但是源(方程式的右侧)必须生成所有这些值。 But usually you don't need to assign values. 但是通常您不需要分配值。 Instead just use x = ... . 而是使用x = ... It's just as fast and memory efficient. 速度和内存效率一样快。

Using x[:] on the RHS does nothing for you. 在RHS上使用x[:]对您没有任何帮助。 If x is a list this makes a copy; 如果x是一个列表,则会进行复制; if x is an array is just returns a view , an array with the same values. 如果x是一个数组,则只返回一个view ,即一个具有相同值的数组。

The key question is, what does your f(...) function accept? 关键问题是,您的f(...)函数接受什么? If it uses operations like + , * and functions like np.sin , you can give it an array, and it will return an array. 如果它使用+*类的操作以及np.sin类的np.sin ,则可以为其提供一个数组,它将返回一个数组。

But if it only works with scalars (that includes using functions like math.sin ), the you have to feed it scalars, ie x[i] . 但是,如果它仅适用于标量(包括使用诸如math.sin类的math.sin ),则您必须为其提供标量,即x[i]

Let's try to unpack that comment (which might be better as an edit to the original question) 让我们尝试解压缩该评论(作为对原始问题的编辑可能会更好)

I have an interval which has to be cut in 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)

For example 例如

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

We can do the x[i]+c for all x and c with broadcasting 我们可以通过广播为所有xcx[i]+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]])

If f is a function like np.sin that takes any array, we can pass xc to that, getting back a like sized array. 如果f是像np.sin这样的函数,它接受任何数组,则可以将xc传递给该函数,从而获得大小相同的数组。

Again with broadcasting we can do the b[n]*f(x[i]+c[n]) calculation 再次使用广播,我们可以进行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]])

and then we can sum, getting back an array shaped just like x : 然后我们可以求和,得到一个形状类似于x的数组:

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

That's the dot or matrix product: 那就是点或矩阵乘积:

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

And as I noted earlier we can complete the action with 正如我前面提到的,我们可以通过

x = b.dot(f(x+c[:,None])

The key to a simple expression like this is f taking an array. 像这样的简单表达式的关键是f接受数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM