【问题标题】:Vectorized Counting 2 Dimensional Numpy Array矢量化计数二维 Numpy 数组
【发布时间】:2018-01-09 11:46:12
【问题描述】:

谁能帮我解释一下如何在没有任何迭代的情况下从 2 个数组中计数(例如使用 numpy)?

示例: 我有两个 numpy 数组,Origin 和destination。起点和终点可以具有相同的值。假设我的数组中有 6 个项目

origin = np.array(['LA', 'SF', 'NY', 'NY', 'LA', 'LA'])

dest = np.array(['SF', 'NY', 'NY', 'SF', 'LA', 'LA'])

第一项来自 LA-SF,第二个 SF-NY,第三个 NY-NY,依此类推。

我想要的结果是

array([[1, 0, 1],
       [0, 2, 1],
       [1, 0, 0]])

其中行代表起点,第一代表纽约,第二代表洛杉矶,第三代表旧金山,列代表目的地,顺序相同。

谢谢!

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    您可以使用np.unique(,return_inverse=1)np.add.at 来做到这一点

    def comm_mtx(origin, dest, keys = None):  # keys -> np.array of strings   
        if keys.size:
            o_lbl = d_lbl = keys
            k_sort = np.argsort(keys)
            o_idx = np.searchsorted(keys, origin, sorter = k_sort)
            d_idx = np.searchsorted(keys, dest, sorter = k_sort)
            o_idx = np.arange(o_idx.size)[k_sort][o_idx]
            d_idx = np.arange(d_idx.size)[k_sort][d_idx]
        else:
            o_lbl, o_idx = np.unique(origin, return_inverse = 1)
            d_lbl, d_idx = np.unique(dest,   return_inverse = 1)
        out = np.zeros((o_lbl.size, d_lbl.size))
        np.add.at(out, (o_idx, d_idx), 1)
        if keys.size:
            return out
        else:
            return o_lbl, d_lbl, out
    

    根据out 的稀疏性,您可能希望改用scipy.sparse.coo_matrix

    from scipy.sparse import coo_matrix as coo
    def comm_mtx(origin, dest):    
        o_lbl, o_idx = np.unique(origin, return_inverse = 1)
        d_lbl, d_idx = np.unique(dest,   return_inverse = 1)
        return o_lbl, d_lbl, coo((np.ones(origin.shape), (o_idx, d_idx)), shape = (o_lbl.size, d_lbl.size))
    

    【讨论】:

    • 这个答案是错误的,因为 OP 说“行指的是原点,首先是 NY,第二是 LA,第三是 SF,并且列指的是具有相同顺序的目的地”,并且np.unique 没有给你这个命令。
    • 虽然如果 OP 改变主意并决定他实际上不需要这个,那么这个答案是正确的并且比我的更好:)
    • 完全正确,让我看看我能不能想出比你更好的东西:P
    • 拜托,我敢肯定有比使用字典映射键更多的 num-pythonic 方式。另外,对稀疏矩阵大喊大叫!
    • 稀疏矩阵的想法真的很酷。我决定接受这个答案,因为顺序对我来说并不重要。谢谢!
    【解决方案2】:

    要实现您所要求的,即让输出矩阵的行以特定顺序对应于键,您可以使用字典将每个唯一元素映射到行索引。

    origin = np.asarray(['LA', 'SF', 'NY', 'NY', 'LA', 'LA'])
    dest = np.asarray(['SF', 'NY', 'NY', 'SF', 'LA', 'LA'])
    
    matrix_map = {'NY': 0, 'LA': 1, 'SF': 2}
    stacked_inputs = np.vstack((origin, dest))
    remapped_inputs = np.vectorize(matrix_map.get)(stacked_inputs)
    
    output_matrix = np.zeros((len(matrix_map), len(matrix_map)), dtype=np.int16)
    np.add.at(output_matrix, (remapped_inputs[0], remapped_inputs[1]), 1)
    print(output_matrix)
    

    哪些输出;

    [[1 0 1]
     [0 2 1]
     [1 0 0]]
    

    根据需要。


    或者,如果您不希望事先对matrix_map 进行硬编码,您可以按如下方式以编程方式构建它;

    stacked_inputs = np.vstack((origin, dest))
    
    matrix_map = {}
    for element in stacked_inputs.flatten():
        matrix_map.setdefault(element, len(matrix_map))
    print(matrix_map)
    
    remapped_inputs = np.vectorize(matrix_map.get)(stacked_inputs)
    

    这不会为您提供所需的顺序,但可以让您使用字典轻松映射与哪个标记相关的行/列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 2011-12-31
      • 2014-08-15
      • 2012-10-31
      • 1970-01-01
      • 2015-02-21
      • 2014-07-29
      相关资源
      最近更新 更多