python - Convert numpy.array to order of elements when duplicate values are present -
i looking efficient way following:
if input is:
np.array([9,0,1,0,3,0])
i want output be:
np.array([0,3,2,3,1,3]) # 9 highest, gets rank 0 # 3 sec highest, gets rank 1 # 1 3rd highest, gets rank 2 # 0's forth highest rank 3
i trying apply next 2d matrix:
input:
a = np.array([[9,0,1,0,3,0], [0,1,2,3,4,5], [0.01,0.3,2,100,1,1], [0,0,0,0,1,1], [4,4,4,4,4,4]])
output:
>>> get_order_array(a) array([[0, 3, 2, 3, 1, 3], [5, 4, 3, 2, 1, 0], [4, 3, 1, 0, 2, 2], [1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0]])
i can accomplish above next solution; however, sense inefficient, hoping can suggest improve way accomplish goal.
def get_order(x): unique_x = np.unique(x) step_1 = np.argsort(unique_x)[::-1] temp_dict = dict(zip(unique_x, step_1)) homecoming np.vectorize(temp_dict.get)(x) def get_order_array(x): new_array = np.empty(x.shape, dtype=np.int) in xrange(x.shape[0]): new_array[i] = get_order(x[i]) homecoming new_array
@jaime's reply great (as usual!). here's alternative, using scipy.stats.rankdata
.
in rankdata
's terminology, want "dense" ranking. want rank values in opposite order usual. accomplish reverse order, we'll pass -a
rankdata
. we'll subtract 1 ranking ranks begin @ 0 instead of 1. finally, want rank rows of two-dimensional array. rankdata
works on one-dimensional data, we'll have loop on rows.
here's code:
import numpy np scipy.stats import rankdata def get_order_array(a): b = np.empty(a.shape, dtype=int) k, row in enumerate(a): b[k] = rankdata(-row, method='dense') - 1 homecoming b if __name__ == "__main__": = np.array([[9,0,1,0,3,0], [0,1,2,3,4,5], [0.01,0.3,2,100,1,1], [0,0,0,0,1,1], [4,4,4,4,4,4]]) print get_order_array(a)
output:
[[0 3 2 3 1 3] [5 4 3 2 1 0] [4 3 1 0 2 2] [1 1 1 1 0 0] [0 0 0 0 0 0]]
python numpy
No comments:
Post a Comment