Fastest way to rank items with multiple values and weightings

后端 未结 2 1864
独厮守ぢ
独厮守ぢ 2021-01-29 07:16

I have a collection of key value pairs like this:

{ 
   \'key1\': [value1_1, value2_1, value3_1, ...], 
   \'key2\': [value1_2, value2_2, value3_2, ...],
   ...
         


        
2条回答
  •  一向
    一向 (楼主)
    2021-01-29 07:36

    You can't get linear-time, but you can do it faster; this looks like a matrix-multiply to me, so I suggest you use numpy:

    import numpy as np
    
    keys = ['key1', 'key2', 'key3']
    
    values = np.matrix([
        [1.1, 1.2, 1.3, 1.4],
        [2.1, 2.2, 2.3, 2.4],
        [3.1, 3.2, 3.3, 3.4]
    ])
    
    weights = np.matrix([[10., 20., 30., 40.]]).transpose()
    
    res = (values * weights).transpose().tolist()[0]
    
    items = zip(res, keys)
    items.sort(reverse=True)
    

    which gives

    [(330.0, 'key3'), (230.0, 'key2'), (130.0, 'key1')]
    

    Edit: with thanks to @Ondro for np.dot and to @unutbu for np.argsort, here is an improved version entirely in numpy:

    import numpy as np
    
    # set up values
    keys = np.array(['key1', 'key2', 'key3'])
    values = np.array([
        [1.1, 1.2, 1.3, 1.4],    # values1_x
        [2.1, 2.2, 2.3, 2.4],    # values2_x
        [3.1, 3.2, 3.3, 3.4]     # values3_x
    ])
    weights = np.array([10., 20., 30., 40.])
    
    # crunch the numbers
    res = np.dot(values, -weights)   # negative of weights!
    
    order = res.argsort(axis=0)  # sorting on negative value gives
                                 # same order as reverse-sort; there does
                                 # not seem to be any way to reverse-sort
                                 # directly
    sortedkeys = keys[order].tolist()
    

    which results in ['key3', 'key2', 'key1'].

提交回复
热议问题