【问题标题】:Indexing numpy arrays only if within bounds仅在范围内索引 numpy 数组
【发布时间】:2022-11-06 02:22:56
【问题描述】:

我有一个形状为(nx,ny) 的二维numpy 数组psi。我想创建一个形状相同的新数组phi,其中对于每个元素phi[i][j],我需要评估一个包含psi[i][j] 和相邻元素psi[i-1][j]psi[i+1][j]psi[i][j+1]psi[i][j-1] 的表达式,除了这些邻居中的任何一个不在psi 范围内的边缘情况外,在表达式中将该元素视为0

我可以使用嵌套的 for 循环并检查边界条件来实现这一点,但我希望尽可能高效地执行此操作。我试过分配

phi[1:-1,1:-1] = f(psi[1:-1,1:-1], psi[0:-2,1:-1], psi[2:,1:-1], psi[1:-1,0:-2], psi[1:-1,2:])

但这不包括会变得混乱的边缘情况,所以如果有一些条件方法只能在界限内引用,否则只是0 它可能会起作用。或者,当然,如果有一种更省时的方法会更好。

【问题讨论】:

  • 你能告诉我们你想要评估的表达式是什么吗?
  • 您可以在 psi 的顶部和底部填充一行零,在左侧和右侧填充一列零。只有这样,您才需要在索引中考虑到这一点。例如,phi[i][j] 将对应于psi[i+1][j+1]
  • @AJH 在 x 和 y 中数值取二阶偏导数作为哈密顿,所以类似于 -0.5*( (psi[i-1][j] + psi[i+1][j] - 2*psi[i][j])/dx**2 + (psi[i][j-1] + psi[i][j+1] - 2*psi[i][j])/dy**2)
  • @stelioslogothetis 不敢相信我没想到,我现在就试试,谢谢!

标签: python arrays numpy indexing conditional-statements


【解决方案1】:

这个问题闻起来像有限差分。您最好的选择是为内部点编写一个(快速,可能是递归的)循环,然后分别遍历边界点,在那里施加所需的边界条件。显然,另一种方法也可以:首先分配边界点,然后遍历内部点。

也就是说,如果您遇到速度问题(可能是因为您的网格很大),您可能需要进行一些优化,因为 python 中的二维数组是 S L O W:

  • 尝试颠倒循环的顺序:在python(NumPy,如果你正在使用它)中,二维数组首先被行遍历。您可能至少想尝试一下。

  • 尝试将您的 2d 事物分配为一个大的 1d 块,其中其唯一索引为 n = i + nx * ji,j 您的原始 2d 索引。同样,尝试先沿行与列运行新索引 n。

这两个建议结合起来应该会给你一个巨大的加速。

【讨论】:

  • 我肯定听说过关于 2d 阵列的事,那我试试冷凝,谢谢!我对必须优化时间很陌生,并且不完全理解您对其他一些事情的意思。如何创建快速内点循环?你的意思是快,因为如果我单独做内部点,我不必检查边界点,检查这些影响时间有那么大吗?遍历顺序如何影响速度?据我了解,引用数组应该始终是同一时间?
  • 将您的 2d 阵列变成 1d 将为您提供与您所拥有的东西相关的最佳性能升级。如果您仍然喜欢 2d 表示法,您可以简单地使用我给您的函数 n(i,j) 对原始 1d psi 进行“查看”。至于如何优化您的内部循环,这将取决于您手头的方程式(泊松或其他方程式。)在我之前的评论中,“快速”与您遍历数组的速度有关,前提是分配psi 的每个元素的操作就足够了。
【解决方案2】:

我已经意识到使用 numpy 数组操作绝对是使代码更快的方法。将它与 np.pad 配对以在矩阵的边缘添加零使这相当简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多