合并数组而不对 Python 上的重叠单元格求和

Merge arrays without summing their overlapping cells on Python

我有数量可变的数组,它们具有相同的大小和相同的 dtype。它们的单元格(在我的代码中称为 pixels)有一个浮点数或一个 NaN。 我想合并这些数组,但有 3 个特定标准。如果对于一个像素(称为重叠像素):

为了做到这一点,我有一个循环遍历每个像素,并评估有多少输入数组具有值。为了满足第一个条件,我写了一组 if/elif/else 条件。为了满足第二个标准,我条件的 else 部分只是一个 np.nansum (因为除 1 个数组外,所有数组在该特定像素处都有 NaN)。

我写的函数一点也不高效,而且非常有限。我怎样才能改进我的代码以处理可变数量的数组进行合并? (超过 3 个阵列)。

我的代码:

import numpy as np

def merger(*args):

    # This function evaluates pixel per pixel the values of 2 to 3 arrays the same size. 
    # Each pixel either has a value or a NaN. We want to merge the arrays without summing their values at overlapping pixels.
    # If at least two arrays have a value for an intersecting pixel, we pick one of the array's value to attribute to the merging pixel in the new array.


    # If we have 2 arrays to merge
    if len(args) == 2:
      
      C = np.empty([args[0].shape[0], args[0].shape[1], args[0].shape[2]],dtype=float)
      
      for b in range(args[0].shape[0]):
        for i in range(args[0].shape[1]):
          for j in range(args[0].shape[2]):

            # If the two similar pixels have a value, take the value of the first array
            if np.isnan(args[0][b,i,j]) == False and np.isnan(args[1][b,i,j]) == False:

              C[b,i,j] = args[0][b,i,j]

            # If all of the pixels are NaN, we input a NaN
            elif np.isnan(args[0][b,i,j]) == True and np.isnan(args[1][b,i,j]) == True:

              C[b,i,j] = np.nan
            
            # Else, take the nansum of the two pixels (because one is a NaN, the other will be the real value)
            else:
              C[b,i,j] = np.nansum([args[0][b,i,j],args[1][b,i,j]])

      
    # If we have 3 arrays to merge (A1, A2 and A3) 
    if len(args) == 3:
      
      C = np.empty([args[0].shape[0], args[0].shape[1], args[0].shape[2]],dtype=float)
      
      for b in range(args[0].shape[0]):
        for i in range(args[0].shape[1]):
          for j in range(args[0].shape[2]):

            # If A1 and A2 have a value but not A3, pick the value of A1. If A1 and A3 have a value but not A2, pick the value of A1
            if np.isnan(args[0][b,i,j]) == False and np.isnan(args[1][b,i,j]) == False and np.isnan(args[2][b,i,j]) == True or np.isnan(args[0][b,i,j]) == False and np.isnan(args[2][b,i,j]) == False and np.isnan(args[1][b,i,j]) == True:

              C[b,i,j] = args[0][b,i,j]

            # If A2 and A3 have a value but not A1, pick the value of A2
            elif np.isnan(args[1][b,i,j]) == False and np.isnan(args[2][b,i,j]) == False and np.isnan(args[0][b,i,j]) == True:

              C[b,i,j] = args[1][b,i,j]

            # If all the arrays have a value, pick the value of A3
            elif np.isnan(args[1][b,i,j]) == False and np.isnan(args[2][b,i,j]) == False and np.isnan(args[2][b,i,j]) == False:

              C[b,i,j] = args[2][b,i,j]

            # If all of the pixels are NaN, we input a NaN
            elif np.isnan(args[1][b,i,j]) == True and np.isnan(args[2][b,i,j]) == True and np.isnan(args[2][b,i,j]) == True:

              C[b,i,j] = np.nan

            # If only one array has a value, nansum will attribute this value to the pixel
            else:
              C[b,i,j] = np.nansum([args[0][b,i,j],args[1][b,i,j], args[2][b,i,j]])




      return C



# Example
A1 = np.array([[[1, 1, 1],[np.nan, np.nan, np.nan], [1, np.nan, 1]],[[1, 1, 1],[np.nan, np.nan, np.nan], [1, np.nan, 1]]])
A2 = np.array([[[1, np.nan, 1],[1, np.nan, np.nan], [1, np.nan, 1]],[[1, 1, 1],[np.nan, np.nan, 1], [np.nan, 1, 1]]])
A3 = np.array([[[1, 1, 1],[np.nan, np.nan, 1], [np.nan, 1, 1]],[[1, np.nan, 1],[1, np.nan, np.nan], [1, np.nan, 1]]])


merger(A1, A2, A3)

array([[[ 1.,  1.,  1.],
        [ 1., nan,  1.],
        [ 1.,  1.,  1.]],

       [[ 1.,  1.,  1.],
        [ 1., nan,  1.],
        [ 1.,  1.,  1.]]])

除非我遗漏了什么,否则这与用 A2 然后 A3 迭代替换 A1 nan 值有什么不同?由于您没有对任何内容求和,而是从其他数组中任意选择一个 non-null 值。

A1 = np.array([[[1, 1, 1],[np.nan, np.nan, np.nan], [1, np.nan, 1]],[[1, 1, 1],[np.nan, np.nan, np.nan], [1, np.nan, 1]]])
A2 = np.array([[[1, np.nan, 1],[1, np.nan, np.nan], [1, np.nan, 1]],[[1, 1, 1],[np.nan, np.nan, 1], [np.nan, 1, 1]]])
A3 = np.array([[[1, 1, 1],[np.nan, np.nan, 1], [np.nan, 1, 1]],[[1, np.nan, 1],[1, np.nan, np.nan], [1, np.nan, 1]]])


A1[np.isnan(A1)] = A2[np.isnan(A1)]
A1[np.isnan(A1)] = A3[np.isnan(A1)]
print(A1)

输出

[[[ 1.  1.  1.]
  [ 1. nan  1.]
  [ 1.  1.  1.]]

 [[ 1.  1.  1.]
  [ 1. nan  1.]
  [ 1.  1.  1.]]]