gpt4 book ai didi

Python/numpy棘手的切片问题

转载 作者:太空宇宙 更新时间:2023-11-03 12:29:48 25 4
gpt4 key购买 nike

我对一些 numpy 的东西有疑问。我需要一个 numpy 数组以一种不寻常的方式运行,方法是返回一个切片作为我切片的数据的 View ,而不是副本。所以这是我想做的一个例子:

假设我们有一个像这样的简单数组:

a = array([1, 0, 0, 0])

我想用数组中的前一个条目更新数组中的连续条目(从左到右移动),使用如下语法:

a[1:] = a[0:3]

这将得到以下结果:

a = array([1, 1, 1, 1])

或者像这样:

a[1:] = 2*a[:3]
# a = [1,2,4,8]

为了进一步说明,我想要以下类型的行为:

for i in range(len(a)):
if i == 0 or i+1 == len(a): continue
a[i+1] = a[i]

除非我想要 numpy 的速度。

numpy 的默认行为是获取切片的副本,所以我实际得到的是这样的:

a = array([1, 1, 0, 0])

我已经将此数组作为 ndarray 的子类,因此如果需要我可以对其进行进一步更改,我只需要右侧的切片在更新左侧的切片时不断更新边。

我是在做梦还是这种魔法是可能的?

更新:这都是因为我正在尝试使用 Gauss-Seidel 迭代来解决线性代数问题,或多或少。这是一个涉及调和函数的特例,我试图避免进入这个,因为它真的没有必要并且可能会进一步混淆事情,但这里是。

算法是这样的:

while not converged:
for i in range(len(u[:,0])):
for j in range(len(u[0,:])):
# skip over boundary entries, i,j == 0 or len(u)
u[i,j] = 0.25*(u[i-1,j] + u[i+1,j] + u[i, j-1] + u[i,j+1])

对吧?但是你可以通过两种方式做到这一点,Jacobi 涉及更新每个元素及其邻居而不考虑你已经进行的更新,直到 while 循环循环,要在循环中执行它,你将复制数组然后从复制的数组更新一个数组。但是,Gauss-Seidel 使用您已经为 i-1 和 j-1 条目中的每一个更新的信息,因此不需要副本,循环应该基本上“知道”,因为在每个单个元素更新后都会重新评估数组.也就是说,每次调用u[i-1,j]或u[i,j-1]这样的条目时,上一次循环计算的信息都会在那里。

我想用一行使用 numpy 切片的漂亮干净的代码来替换这种缓慢而丑陋的嵌套循环情况:

u[1:-1,1:-1] = 0.25(u[:-2,1:-1] + u[2:,1:-1] + u[1:-1,:-2] + u[1:-1,2:])

但结果是 Jacobi 迭代,因为当你获取切片时:u[:,-2,1:-1] 你复制了数据,因此切片不知道所做的任何更新。现在 numpy 还在循环吗?它不是并行的,它只是一种更快的循环方式,看起来像 python 中的并行操作。我想通过对 numpy 进行某种黑客攻击来利用这种行为,以便在我获取切片时返回一个指针而不是一个副本。正确的?然后每次 numpy 循环时,该切片将“更新”或实际上只是复制更新中发生的任何事情。为此,我需要将数组两侧的切片作为指针。

无论如何,如果有一些非常非常聪明的人那么棒,但我几乎已经听天由命地相信唯一的答案是在 C 中循环。

最佳答案

迟到的答案,但这出现在谷歌上,所以我可能会指出 OP 想要的文档。您的问题很清楚:使用 NumPy 切片时,会创建临时文件。在快速调用 weave.blitz 中封装您的代码,以摆脱临时变量并获得您想要的行为。

阅读 PerformancePython tutorial 的 weave.blitz 部分了解全部详情。

关于Python/numpy棘手的切片问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1587367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com