【问题标题】:Python, numpy.array slicing, altering array values with slicesPython,numpy.array 切片,用切片改变数组值
【发布时间】:2017-10-04 05:12:04
【问题描述】:

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

我有具有 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[:] 这样的切片指令只是贯穿我的整个对象。有没有办法以某种方式保存我目前所在的索引? 我试图搜索但一无所获。另一个问题是我什至不知道如何正确地提出搜索请求......

【问题讨论】:

  • 贴一个我们可以效仿的真实例子。你在做什么,你尝试过什么。例如,如果不知道f 是什么,就不可能有效地回答这个问题。
  • F 只是一个函数。 f= λx: np.sin(x)
  • 只需y = np.sin(x + a) * b。除非您要在 x 的子部分上进行操作,否则无需使用切片符号
  • 你知道np.sin 是一个完全向量化的函数吗?
  • 好的,尝试解释我的问题。 (我不是 niteve 演讲者,所以请原谅语言错误)。

标签: python arrays numpy slice


【解决方案1】:

你可能会混淆两个问题

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

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]

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

我有一个间隔,必须切碎。

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

我们可以通过广播为所有xc 执行x[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]])

如果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 接受一个数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2020-12-11
    • 2011-08-30
    • 2013-04-12
    • 2021-11-26
    • 1970-01-01
    • 2014-02-03
    相关资源
    最近更新 更多