2017-08-02 103 views
1

任何人都可以帮助解释我怎么才能从2个数组没有任何迭代(例如使用numpy)计数?向量化计数2维Numpy阵列

例如: 我有两个numpy阵列,Origin和destiation。起点和目的地可以具有相同的值。让说,我有我的阵列

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

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

的第一项是从LA-SF,第二SF-NY,NY第三-NY等6个项目。

结果,我想是

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

其中行是指起源,第一个是NY,第二个是LA,和第三是SF,且列指的是具有相同的顺序的目的地。

谢谢!

回答

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)) 
+0

这个答案是错误的,因为OP表示“哪一行是指原点,第一个是NY,第二个是LA,第三个是SF,并且该列是指具有相同顺序的目的地”,以及'np.unique'不会给你这个订单。 –

+0

虽然如果OP改变了主意,并决定他实际上不需要这个,那么这个答案是正确的,并且比我的更好:) –

+0

非常正确,让我看看我能不能找到比你更好的东西:P –

0

要实现你问什么,即按照特定顺序使输出矩阵的行与键对应,您可以使用字典将每个唯一元素映射到行索引。

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) 

这不会给你想要的顺序,但将允许您使用词典轻松映射哪一行/列涉及令牌。