2017-08-02 115 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) 

這不會給你想要的順序,但將允許您使用詞典輕鬆映射哪一行/列涉及令牌。