nans的下一个邻居

时间:2018-07-17 06:41:39

标签: python numpy nan nearest-neighbor

我正在寻找一种有效的方法来获取测量值之间有NaNs的数组的每个条目的最近邻居。我想做的是使用下一个邻居对每个值进行插值或外推,但是NaNs通常搞砸了我为执行此类操作而发现的函数-所以我写了一个相当荒谬的复杂函数,虽然可以,但是当数组的值超过1k左右时,效率会变得太低。

因此,我将给函数提供要计算的值(newIs = [0,1,2,3,4])和测量值(Is = [np.nan,np.nan,0.1,0.7,1.2,np.nan,np.nan,2.6,3.8,4.2,6.3,np.nan,np.nan,np.nan])。我想要得到的是newIs

中每个值的两个索引数组

可视化:

INPUT:

newIs = [0,1,2,3,10]

Is = [np.nan,np.nan,0.1,0.7,1.2,np.nan,np.nan,2.6,3.8,4.2,6.3,np.nan,np.nan,np.nan]

[Input] [Index-1,Index-2]

In: [0] Out: [2,3] -- points to 0.1 and 0.7 as nearest neighbours

In: [1] Out: [3,4] -- points to 0.7 and 1.2

In: [2] Out: [4,7] -- points to 1.2 and 2.6

In: [3] Out: [7,8] -- points to 2.6 and 3.8

In: [10] Out: [9,10] -- points to 4.2 and 6.3

因此,对于0.1以下的每个值,我将得到[2,3],对于6.3以上的每个值,我将得到[9,10]。当我只想插值时,只需检查我的“期望”值是否在计算的索引之间。

我使用的是以下功能(添加了一些注释以提高可读性):

def find_interpolation_indices(Is,newIs):# BaMa:: numpy arrays as inputs
    maxx = len(Is)-1
    arrayLeft = []
    arrayRight = []
    for curr in newIs:# BaMa:: 'safety first' -> lots of checks to make sure indices are correct
        index = 0
        right = 0
        left = 0
        for k in range(0,len(Is)):# BaMa:: instead write a search fct yourself like so...
            if(np.isnan(Is[k])):
                pass
            elif(Is[k] > curr):
                index = k
                break
        if(index > maxx):
            index = maxx
        direction = 0
        while(np.isnan(Is[index]) and direction == 0):
            index += 1
            if(index >= maxx):
                index = maxx
                direction+=1
        if(direction >= 1):
            while(np.isnan(Is[index])):
                index -= 1
                if(index <= 0):
                    print('\x1b[1;31;43m' + 'ERROR: Interpolation fail 0 -> nothing found for ', Is[index], ' and ', curr, ' ! \x1b[0m')
        if(Is[index] <= curr):# BaMa:: (1/2) current at index value is checked, should be the standard case
            left = index
            right = index+1
            while(left < 0):
                left+=1
                right+=1
            while(right > maxx):
                left-=1
                right-=1
            direction = 0
            while(np.isnan(Is[right]) and direction == 0):# BaMa:: move right index up until value is found
                right+=1
                if(right > len(Is)-1):# BaMa:: if no value is ever found...
                    direction+=1
                    right-=1
            if(direction >=1):# BaMa::...set right index to value and move left index down
                right = index
                left = index-1
                while(np.isnan(Is[left])):# BaMa:: if nothing is found again, print out an Error
                    left-=1
                    if(left <= 0):
                        print('\x1b[1;31;43m' + 'ERROR: Interpolation fail 1 -> nothing found for ', Is[index], ' and ', curr, ' ! \x1b[0m')
                        left+=1
                        break
        elif(Is[index] > curr):# BaMa:: (2/2) current at index value is checked, should be the standard case
            right = index
            left = index-1
            while(left < 0):
                left+=1
                right+=1
            while(right > maxx):
                right-=1
                left-=1
            direction = 0
            while(np.isnan(Is[left]) and direction == 0):# BaMa:: move left index down until value is found
                left-=1
                if(left <= 0):# BaMa:: if no value is ever found...
                    direction+=1
                    left = 0
            if(direction >= 1):# BaMa:: ...set left index to value and move right index up
                left = index
                right = index+1
                while(np.isnan(Is[right])):# BaMa:: 
                    right+=1
                    if(right >= len(Is)-1):
                        print('\x1b[1;31;43m' + 'ERROR: Interpolation fail 2 -> nothing found for ', Is[index], ' and ', curr, ' ! \x1b[0m')
                        right-=1
                        break
        if(right < left):# BaMa:: last check before relaying final values
            print('\x1b[1;31;43m' + 'ERROR: Interpolation fail 3 -> RIGHT < LEFT! \x1b[0m')
            print("left=", left, " right=", right)
        elif(right == left):
            print('\x1b[1;31;43m' + 'ERROR: Interpolation fail 4 -> RIGHT == LEFT! \x1b[0m')
            print("left=", left, " right=", right)
        elif(np.isnan(Is[right]) or np.isnan(Is[left])):
            print('\x1b[1;31;43m' + 'ERROR: Interpolation fail 5 -> Is[left]=', Is[left], ' Is[right] =', Is[right], ' \x1b[0m')
            print("left=", left, " right=", right)
        elif(right > maxx or left > maxx or right < 0 or left < 0):
            print('\x1b[1;31;43m' + 'ERROR: Interpolation fail 6 -> Is[left]=', Is[left], ' Is[right] =', Is[right], ' \x1b[0m')
            print("left=", left, " right=", right)
        else:
            arrayLeft.append(left)
            arrayRight.append(right)
    return arrayLeft,arrayRight

0 个答案:

没有答案