合并数组而不对 Python 上的重叠单元格求和
Merge arrays without summing their overlapping cells on Python
我有数量可变的数组,它们具有相同的大小和相同的 dtype。它们的单元格(在我的代码中称为 pixels
)有一个浮点数或一个 NaN。
我想合并这些数组,但有 3 个特定标准。如果对于一个像素(称为重叠像素):
- 至少 2 个数组有一个值(非 NaN):合并数组中重叠像素的属性仅为输入数组 1 的值。
- 只有 1 个输入数组有一个值,将此输入数组像素的值归因于合并数组中的重叠像素。
- 如果 none 个输入数组具有特定像素的值,我们在重叠像素中写入一个
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.]]])
除非我遗漏了什么,否则这与用 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.]]]
我有数量可变的数组,它们具有相同的大小和相同的 dtype。它们的单元格(在我的代码中称为 pixels
)有一个浮点数或一个 NaN。
我想合并这些数组,但有 3 个特定标准。如果对于一个像素(称为重叠像素):
- 至少 2 个数组有一个值(非 NaN):合并数组中重叠像素的属性仅为输入数组 1 的值。
- 只有 1 个输入数组有一个值,将此输入数组像素的值归因于合并数组中的重叠像素。
- 如果 none 个输入数组具有特定像素的值,我们在重叠像素中写入一个
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.]]])
除非我遗漏了什么,否则这与用 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.]]]