【问题标题】:Calculations with numpy roll over 3d data使用 numpy 计算翻转 3d 数据
【发布时间】:2017-09-28 10:38:50
【问题描述】:

我有一个 3d 数据,想计算距原点所有可能距离的数据点乘积的平均值。我有一个巨大的网格 (128^3-1024^3),而我现在正在做的事情并没有在几个小时内给出答案。

# u read from a file
import numpy as np
for icx in range(0,128):
    for icy in range(0,128):
        for icz in range(0,128):
            cukin[icx,icy,icz] = np.mean((u*np.roll(np.roll(np.roll(u,icx, axis=0),icy, axis=1),icz, axis=2))

有没有办法避免这个问题出现循环?

玩具示例:

cukin = np.zeros((2,2,2))
u = np.mgrid[1:5:1,1:5:1,1:5:1]
for icx in range(0,2):
    for icy in range(0,2):
        for icz in range(0,2):
            cukin[icx,icy,icz] = np.mean((u*np.roll(np.roll(np.roll(u,icx, axis=0),icy, axis=1),icz, axis=2)))

给cukin

[[[ 7.5   7.  ]
  [ 7.    6.5 ]]

 [[ 6.25  6.25]
  [ 6.25  6.25]]]

【问题讨论】:

  • 可以简化roll命令:np.roll(a, (i,j,k))有效。
  • @VBB 仍然无法避免循环。遍历循环是耗时的部分。
  • 制作一个包含输入数据的程序的玩具版本,以便我们可以运行它。
  • @JohnZwinck 按照您的建议使用玩具版本更新问题。

标签: python python-2.7 loops numpy for-loop


【解决方案1】:

尝试使用迭代器而不是列表(range 创建一个列表),它们消耗的内存要少得多。要一次遍历所有位置索引,您可以使用itertools.product。同时滚动所有轴,而不是调用嵌套的np.roll 三次:

from itertools import product as prod
import numpy as np

rng_x = xrange(128)
rng_y = xrange(128)
rng_z = xrange(128)
xyz_ids = prod(rng_x, rng_y, rng_z)

# NOTE: the order of the axis in numpy arrays is inverse
for i, j, k in xyz_ids:
    cukin[k, j, i] = np.mean(u * np.roll(u, [k, j, i], axis=[0, 1, 2]))

不确定是否会输出您期望的结果。让我知道它是否有效。您应该考虑添加一个示例,说明什么是 u 和相应的预期输出。

【讨论】:

  • 这仍然不能避免循环,所以需要很多时间。我已经用一个玩具示例更新了这个问题。
  • 你总是可以使用列表推导:cukin = np.array([np.mean(u * np.roll(u, [k, j, i], axis=[0, 1, 2])) for i, j, k in xyz_ids]).reshape(2, 2, 2)
  • 但我猜它仍然运行超过 3 个循环?它需要同样长的时间!
  • 每个轴有 128 个元素的立方体有 2097152 个元素......无论如何,它不会运行超过 3 个循环,而是一个(更长的)迭代器。也许您应该考虑更改您正在处理的数据类型。默认情况下,numpy 使用 float64 精度。使用较小的浮点数或整数(如果可能)应该加快计算速度。
  • 抱歉,刚刚发现列表理解中的轴是错误的。这输出与您的玩具示例相同:cukin = np.array([np.mean(u * np.roll(u, [k, j, i], axis=[0, 1, 2])) for k, j, i in xyz_ids]).reshape(2, 2, 2)
猜你喜欢
  • 2017-01-14
  • 2022-11-05
  • 2019-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多