【问题标题】:Efficiently copying values from one ndarray to another on unequal sized arrays在大小不等的数组上有效地将值从一个 ndarray 复制到另一个
【发布时间】:2020-07-21 16:11:37
【问题描述】:

我有两个不同大小的数组,但我试图用匹配的“键”上的第二个数组中的值覆盖第一个数组中的一些值。我的实际问题可能有很多很多行,我已经确定这目前正在阻碍我的程序。

编辑:我没有意识到 a1 中可能存在重复值,应该保持重复。我在 np.array 示例中添加了一个这样的示例。

示例:

import numpy as np

# first two columns are 'keys', overwrite the 3rd column in a1 with the 3rd column from a2
# some values may be missing from a2. Those should keep the value in a1

a1 = np.array([[ 0.0,  2.0,  10.0 ],
               [ 0.0,  2.0,  10.0 ],
               [ 0.0,  3.0,  10.0 ],
               [ 1.0,  3.0,  10.0 ],
               [ 1.0, 13.0,  10.0 ],
               [ 2.0,  2.0,  10.0 ],
               [ 2.0,  5.0,  10.0 ]])

a2 = np.array([[ 0.0,  2.0,  0.0   ],
               [ 0.0,  3.0,  0.713 ],
               [ 1.0,  3.0,  0.713 ],
               [ 1.0, 13.0,  1.0   ],
               [ 2.0,  2.0,  0.0   ]])

# wanted result:
np.array([[ 0.0,  2.0,  0.0   ],
          [ 0.0,  2.0,  0.0   ],
          [ 0.0,  3.0,  0.713 ],
          [ 1.0,  3.0,  0.713 ],
          [ 1.0, 13.0,  1.0   ],
          [ 2.0,  2.0,  0.0   ],
          [ 2.0,  5.0,  10.0   ]])

当我执行这种蛮力操作时,我会简单地获取 a2 中的每一行并循环遍历 a1 中的每一行以替换匹配项上的值,但是有没有一种方法可以更有效地执行此操作?某种方式来对至少一个循环上的操作进行矢量化?我的实际情况涉及两个数组中的许多行,这需要很长时间。

【问题讨论】:

    标签: python numpy optimization


    【解决方案1】:

    你会考虑其他包,比如 Pandas 吗?

    import pandas as pd
    
    d2 = pd.DataFrame(a2).set_index([0,1])
    d1 = pd.DataFrame(a1).set_index([0,1])
    
    d1.update(d2)
    d1.reset_index().values
    

    输出:

    array([[ 0.   ,  2.   ,  0.   ],
           [ 0.   ,  2.   ,  0.   ],
           [ 0.   ,  3.   ,  0.713],
           [ 1.   ,  3.   ,  0.713],
           [ 1.   , 13.   ,  1.   ],
           [ 2.   ,  2.   ,  0.   ],
           [ 2.   ,  5.   , 10.   ]])
    

    【讨论】:

      【解决方案2】:

      连接 a2a1 并仅保留前 2 列的唯一行。

      a_all = np.r_[a2, a1]
      a_all = a_all[np.unique(a_all[:, :2], axis=0, return_index=True)[1]]
      

      【讨论】:

      • 请查看编辑,抱歉没有注意到这种情况。
      【解决方案3】:

      如果第三列正在更新并且您想使用 pandas:

      import numpy as np
      import pandas as pd
      
      a1 = np.array([[ 0.0,  2.0,  10.0 ],
                     [ 0.0,  2.0,  10.0 ],
                     [ 0.0,  3.0,  10.0 ],
                     [ 1.0,  3.0,  10.0 ],
                     [ 1.0, 13.0,  10.0 ],
                     [ 2.0,  2.0,  10.0 ],
                     [ 2.0,  5.0,  10.0 ]])
      
      a2 = np.array([[ 0.0,  2.0,  0.0   ],
                     [ 0.0,  3.0,  0.713 ],
                     [ 1.0,  3.0,  0.713 ],
                     [ 1.0, 13.0,  1.0   ],
                     [ 2.0,  2.0,  0.0   ]])
      
      
      d1 = pd.DataFrame(a1)
      
      d2 = pd.DataFrame(a2)
      
      d3 = d2.set_index([0,1])[[2]].combine_first(d1.set_index([0,1])[[2]]).reset_index().to_numpy()
      d3
      

      输出:

      array([[ 0.   ,  2.   ,  0.   ],
             [ 0.   ,  2.   ,  0.   ],
             [ 0.   ,  3.   ,  0.713],
             [ 1.   ,  3.   ,  0.713],
             [ 1.   , 13.   ,  1.   ],
             [ 2.   ,  2.   ,  0.   ],
             [ 2.   ,  5.   , 10.   ]])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-10
        • 2013-11-08
        • 1970-01-01
        • 2012-06-26
        • 1970-01-01
        • 2012-09-28
        • 1970-01-01
        相关资源
        最近更新 更多