社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

Nihilum • 3 年前 • 1217 次点击  

我有不同数量的数组,它们的大小和数据类型都相同。他们的细胞(称为 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.]]])
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/130469
 
1217 次点击  
文章 [ 1 ]  |  最新文章 3 年前
Chris
Reply   •   1 楼
Chris    3 年前

除非我遗漏了什么,否则这和用A2然后A3迭代替换A1 nan值有什么不同?因为你没有求和,你可以从其他数组中任意选取一个非空值。

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.]]]