我有不同数量的数组,它们的大小和数据类型都相同。他们的细胞(称为
pixels
在我的代码中)要么有一个浮点数,要么有一个NaN。
我想合并这些数组,但有3个特定的标准。如果是一个像素(称为重叠像素):
-
至少有2个数组有一个值(非NaN):将1个输入数组的值仅指定给合并数组中的重叠像素。
-
只有一个输入数组有一个值,将该输入数组的像素值指定给合并数组中的重叠像素。
-
如果没有一个输入数组具有特定像素的值,我们将写入
np.nan
在重叠像素中。
为了做到这一点,我有一个循环通过每个像素,并评估有多少个输入数组有一个值。为了满足第一个条件,我编写了一组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.]]])