Python 有没有一种更像Numpy的方法来插值我的光栅?

Python 有没有一种更像Numpy的方法来插值我的光栅?,python,numpy,raster,Python,Numpy,Raster,我编写了一个小函数来插值不规则采样光栅图像的时间序列,以便它们在时间上均匀分布(如下)。它工作的很好,但我只是知道从它看,我错过了一些捷径。我正在寻找一个Numpy忍者给我一些专业的提示,告诉我如何提高我的语法,也许还能提高一点性能 干杯 将numpy导入为np def内部光栅(光栅、时钟、采样因子=1): n帧=圆形(len(chrons)*采样因子) interchrons=np.linspace(np.min(chrons)、np.max(chrons)、nFrames) 帧、行、列、通道

我编写了一个小函数来插值不规则采样光栅图像的时间序列,以便它们在时间上均匀分布(如下)。它工作的很好,但我只是知道从它看,我错过了一些捷径。我正在寻找一个Numpy忍者给我一些专业的提示,告诉我如何提高我的语法,也许还能提高一点性能

干杯

将numpy导入为np
def内部光栅(光栅、时钟、采样因子=1):
n帧=圆形(len(chrons)*采样因子)
interchrons=np.linspace(np.min(chrons)、np.max(chrons)、nFrames)
帧、行、列、通道=光栅.shape
interpRasters=np.zero((n帧、行、列、通道),dtype='uint8')
出局=[]
对于范围内的行(行):
对于范围内的列(列):
对于范围内的通道(通道):
像素系列=光栅[:,行,列,通道]
内插器[:,行,列,通道]=np.interp(
时间间隔,
时间,
像素序列
)
返回内插器

由于要查找的y值必须是1d,因此我看不到不在np.数组中循环的方法。如果光栅和内光栅阵列按照函数中的使用方式进行重塑,则无需显式索引即可使用一个循环。这给了我大约10%的速度提高了我编的测试数据

import numpy as np

frames = 10
rows = 5
cols = 10
channels = 3

np.random.seed(1234)

rasters = np.random.randint(0,256, size=(frames, rows, cols, channels))
chrons = np.random.randint(0, 256, size  = 10 )


# The original function.
def interp_rasters(rasters, chrons, sampleFactor = 1):
    nFrames = round(len(chrons) * sampleFactor)
    interpChrons = np.linspace(np.min(chrons), np.max(chrons), nFrames)
    frames, rows, cols, channels = rasters.shape
    interpRasters = np.zeros((nFrames, rows, cols, channels), dtype = 'uint8')
    outs = []
    for row in range(rows):
        for col in range(cols):
            for channel in range(channels):
                pixelSeries = rasters[:, row, col, channel]
                interpRasters[:, row, col, channel] = np.interp(
                    interpChrons,
                    chrons,
                    pixelSeries
                    )
    return interpRasters

def interp_rasters2(rasters, chrons, sampleFactor = 1):
    nFrames = round(len(chrons) * sampleFactor)
    interpChrons = np.linspace(np.min(chrons), np.max(chrons), nFrames)
    frames, rows, cols, channels = rasters.shape
    interpRasters = np.zeros((nFrames, rows, cols, channels), dtype = 'uint8')

    # Create reshaped arrays pointing to the same data 
    dat_in = rasters.reshape(frames, rows*cols*channels).T  
    # shape (r*c*c, frames)

    dat_out = interpRasters.reshape(nFrames, rows*cols*channels).T  
    # shape (r*c*c, frames)

    for pixelseries, row_out in zip(dat_in, dat_out):
        # Loop through all data in one loop.
        row_out[:] = np.interp( interpChrons, chrons, pixelseries )
    return interpRasters  
    # As dat_out and interpRasters share the same data return interpRasters

print(np.isclose(interp_rasters(rasters, chrons), interp_rasters2(rasters, chrons)).all())
# True  # The results are the same from the two functions.

%timeit interp_rasters(rasters, chrons)
# 568 µs ± 2.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit interp_rasters2(rasters, chrons)
# 520 µs ± 239 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
编辑还有np.apply_沿_轴。这将删除任何显式for循环,减少代码量,但速度比以前的解决方案慢

def interp_rasters3(rasters, chrons, sampleFactor = 1):
    nFrames = round(len(chrons) * sampleFactor)
    interpChrons = np.linspace(np.min(chrons), np.max(chrons), nFrames)

    def func( arr ):  # Define the function to apply along the axis
        return np.interp( interpChrons, chrons, arr )

    return np.apply_along_axis( func, 0, rasters ).astype( np.uint8 )

print(np.isclose(interp_rasters(rasters, chrons), interp_rasters3(rasters, chrons)).all())
# True
我想如果速度不是很关键的话,我会在6个月内更好地理解版本3,而不是版本1或2