【问题标题】:Iterate over two arrays looking up values in a dict遍历两个数组查找字典中的值
【发布时间】:2014-06-18 06:33:17
【问题描述】:

所以我有一本字典:

LCM_SCS = { 
        (1, "A"): 36, (1, "B"): 60, (1, "C"): 73, (1, "D"): 79, 
        (2, "A"): 36, (2, "B"): 60, (2, "C"): 73, (2, "D"): 79, 
        (3, "A"): 74, (3, "B"): 83, (3, "C"): 88, (3, "D"): 90, 
        (4, "A"): 68, (4, "B"): 79, (4, "C"): 86, (4, "D"): 89, 
        (5, "A"): 30, (5, "B"): 58, (5, "C"): 71, (5, "D"): 78, 
        (6, "A"): 39, (6, "B"): 61, (6, "C"): 74, (6, "D"): 80, 
        (7, "A"): 39, (7, "B"): 61, (7, "C"): 74, (7, "D"): 80, 
        (8, "A"): 39, (8, "B"): 61, (8, "C"): 74, (8, "D"): 80, 
        (10, "A"): 30, (10, "B"): 48, (10, "C"): 65, (10, "D"): 73, 

我还有两个数组,它们组合起来为上面的字典提供元组键:

数组 1:

array1 = np.array([[1, 1, 1],
          [2, 2, 3],
          [2, 4, 5]])

数组 2:

array2 = np.array([["A", "A", "A"],
             ["B", "B", "B"],
             ["C", "C", "C"]])

我的代码是:

Numbers = np.empty_like(array1)


for [x, y], (value1, value2) in np.ndenumerate(izip(array1, array2)):
        CN_numbers[x, y] = LCM_SCS.get((value1, value2))

    return Numbers

此代码不起作用。我想要的是一个看起来像这样的数组:

Numbers = array([[36, 36, 36],
          [60, 60, 83],
          [73, 86, 71]])

所以基本上我有两个数组,其中包含用作查找字典的键的值,我不确定如何在代码中实现它。

任何建议或帮助将不胜感激。

谢谢,

尼克

使用矢量化的解决方案:

a_new = np.empty_like(array1)

def get_CN_numbers(a1, a2):
    return LCM_SCS[(a1, a2)]  # your basic scalar-operation

V_get_CN = np.vectorize(get_CN_numbers)

a_new = V_get_CN(array1, array2)

print a_new

【问题讨论】:

    标签: python arrays numpy dictionary vectorization


    【解决方案1】:

    vectorize它。

    @numpy.vectorize
    def get_CN_numbers(a1, a2):
        return LCM_SCS[(a1,a2)]  # your basic scalar-operation
    
    get_CN_numbers(array1, array2)
    =>
    array([[36, 36, 36],
           [60, 60, 83],
           [73, 86, 71]])
    

    一般来说,使用vectorize 是扩展标量操作(在您的情况下,通过标量键从字典中获取值)以处理数组(在您的情况下,是两个键数组)的简单方法。正如您已经发现的那样,vectorize 为您处理的棘手部分是保持形状。

    这提供了简单性,但不一定是速度,因为vectorize 是使用 python-space 循环实现的。

    【讨论】:

    • 嗨,这听起来似乎是一个非常简单的解决方案,但我似乎无法让它发挥作用。我收到错误消息:“TypeError: unhashable type: 'numpy.ndarray'”
    • 谢谢!这将使我以后要做的事情变得更容易。
    【解决方案2】:

    试试这个:

    >>> new_array = np.rec.fromarrays((array1,array2),names='x,y')     # This will generate all keys that you'll look value for.
    >>> print new_array
    [[(1, 'A') (1, 'A') (1, 'A')]
     [(2, 'B') (2, 'B') (3, 'B')]
     [(2, 'C') (4, 'C') (5, 'C')]]
    >>> result = np.zeros([3,3],dtype=int)      #Having issue to modify directly on new_array so I initialized a new numpy array to store result
    >>> for (x,y), value in np.ndenumerate(new_array):
        result[x][y] = LCM_SCS[tuple(value)]
    
    >>> print result
    [[36 36 36]
     [60 60 83]
     [73 86 71]]
    

    【讨论】:

      【解决方案3】:
      LCM_SCS = { 
              (1, "A"): 36, (1, "B"): 60, (1, "C"): 73, (1, "D"): 79, 
              (2, "A"): 36, (2, "B"): 60, (2, "C"): 73, (2, "D"): 79, 
              (3, "A"): 74, (3, "B"): 83, (3, "C"): 88, (3, "D"): 90, 
              (4, "A"): 68, (4, "B"): 79, (4, "C"): 86, (4, "D"): 89, 
              (5, "A"): 30, (5, "B"): 58, (5, "C"): 71, (5, "D"): 78, 
              (6, "A"): 39, (6, "B"): 61, (6, "C"): 74, (6, "D"): 80, 
              (7, "A"): 39, (7, "B"): 61, (7, "C"): 74, (7, "D"): 80, 
              (8, "A"): 39, (8, "B"): 61, (8, "C"): 74, (8, "D"): 80, 
              (10, "A"): 30, (10, "B"): 48, (10, "C"): 65, (10, "D"): 73}
      
      array1 = np.array([[1, 1, 1], [2, 2, 3], [2, 4, 5]]).tolist()
      array2 = np.array([["A", "A", "A"], ["B", "B", "B"], ["C", "C", "C"]]).tolist()
      
      array1 = [y for sub in array1 for y in sub]
      array2 = [y for sub in array2 for y in sub]
      results = [LCM_SCS[(array1[k], array2[k])] for k in range(len(array1))]
      

      输出:

      [36, 36, 36, 60, 60, 83, 73, 86, 71]
      

      您可以根据需要将其转换为列表列表,甚至将其设为np.array()

      【讨论】:

      • 谢谢,但您的结果生成的输出不是我想要的。我想只使用字典中的新值来保持数组的形状。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多