Python:快速离散插值

2024-06-28 11:30:22 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个表示离散坐标变换函数的4D数组

arr[x_in, y_in, z_in] = [x_out, y_out, z_out]

我想将arr插入到包含更多元素的网格中(假设arr中的样本最初是从较高元素立方体的规则间隔网格中提取的)。 我试过scipy的RegularGridInterpolator,但是速度相当慢:

import numpy as np
from scipy.interpolate import RegularGridInterpolator
from time import time

target_size   = 32
reduced_size  = 5

small_shape = (reduced_size,reduced_size,reduced_size,3)
cube_small  = np.random.randint(target_size, size=small_shape, dtype=np.uint8)

igrid = 3*[np.linspace(0, target_size-1, reduced_size)]
large_shape = (target_size, target_size, target_size,3)
cube_large  = np.empty(large_shape)

t0 = time()
interpol = RegularGridInterpolator(igrid, cube_small)
for x in np.arange(target_size):
    for y in np.arange(target_size):
        for z in np.arange(target_size):
            cube_large[x,y,z] = interpol([x,y,z])
print(time()-t0)

有没有什么算法更适合这个任务?也许有什么东西可以利用这个事实,在这个例子中,我只对每个点的离散整数值感兴趣


Tags: inimporttargetforsizetimenpout
2条回答

事实上,正如 Crivella似乎更有效。我正在添加一个仅限numpy的版本,它似乎比itertools快2倍左右:

target_size = 256

... # Same as above

def do_new():
    t0 = time()
    grid = np.meshgrid(*3*[np.arange(target_size)], indexing='ij')
    grid = grid[::-1]
    grid = np.stack(grid).T
    ret  = interpol(grid)
    print(f"{time()-t0}")
    return ret

c1 = improved_method()
c2 = do_new()
print((c1==c2).all())

输出:

IMPROVED METHOD: 13.865211009979248
6.268443584442139
True

我真的不能对网格的生成说什么,因为我不能完全确定您正在尝试做什么。 但就提高效率而言,使用三重for循环而不是使用广播会大大降低代码的速度

import itertools
import numpy as np
from scipy.interpolate import RegularGridInterpolator
from time import time

target_size   = 32
reduced_size  = 5

small_shape = (reduced_size,reduced_size,reduced_size,3)
cube_small  = np.random.randint(target_size, size=small_shape, dtype=np.uint8)


igrid = 3*[np.linspace(0, target_size-1, reduced_size)]


large_shape = (target_size, target_size, target_size,3)
cube_large  = np.empty(large_shape)

def original_method():
    t0 = time()

    interpol = RegularGridInterpolator(igrid, cube_small)
    for x in np.arange(target_size):
        for y in np.arange(target_size):
            for z in np.arange(target_size):
                cube_large[x,y,z] = interpol([x,y,z])

    print('ORIGINAL METHOD: ', time()-t0)
    return cube_large

def improved_method():
    t1 = time()
    interpol = RegularGridInterpolator(igrid, cube_small)

    arr = np.arange(target_size)
    grid = np.array(list(itertools.product(arr, repeat=3)))
    cube_large = interpol(grid).reshape(target_size, target_size, target_size, 3)

    print('IMPROVED METHOD:', time() - t1)

    return cube_large


c1 = original_method()
c2 = improved_method()

print('Is the result the same?  ', np.all(c1 == c2))

输出

ORIGINAL METHOD:  6.9040000438690186
IMPROVED METHOD: 0.026999950408935547
Is the result the same?   True

相关问题 更多 >