我正在查看问题Fastest way to rank items with multiple values and weightings,并提出了以下解决方案,但还有两个问题:
import numpy as np
# set up values
keys = np.array([
['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()
# crunch the numbers
res = values * weights
# combine results with labels
items = np.hstack((np.array(res), keys))
# !First problem - .hstack has promoted the first column from float64 to S4:
# array([['130.', 'key1'],
# ['230.', 'key2'],
# ['330.', 'key3']],
# dtype='|S4')
# How can I force it to stay numeric?
items.sort(reverse=True) # doesn't work, no 'reverse' argument
# !Second problem - how to sort the array in descending order?
答案 0 :(得分:2)
您可以将res
和keys
合并到结构化数组中:
import numpy.lib.recfunctions as recfunctions
items = recfunctions.merge_arrays([res,keys])
由于np.sort
没有reverse=True
标志,我认为您可以做的最好的事情是反转返回的数组(例如items[::-1]
)或者取消{{1}的负数}}:
res
产量
import numpy as np
import numpy.lib.recfunctions as recfunctions
# set up values
keys = np.array([
['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()
# crunch the numbers
res = values * weights
# combine results with labels
res = np.asarray(-res)
items = recfunctions.merge_arrays([res,keys])
items.dtype.names = ['res', 'key']
items.sort(order=['res'])
print(items)
请注意[(-330.0, 'key3') (-230.0, 'key2') (-130.0, 'key1')]
只是一个Python便利功能。它使用refunctions.merge_arrays
和zip
。避免加入np.fromiter
和res
肯定会更快,而是使用keys
查找排序argsort
的索引并使用这些索引重新排序res
:< / p>
keys
产量
import numpy as np
# set up values
keys = np.array([
['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()
# crunch the numbers
res = values * weights
# combine results with labels
res = np.squeeze(np.asarray(res))
idx = np.argsort(res)[::-1]
print(keys[idx])
print(res[idx])
答案 1 :(得分:1)
您可以使用numpy数组的argsort
方法对具有可对其他数组进行排序的索引的键进行排序。
import numpy as np
# set up values
keys = np.array([
['key1'],
['key2'],
['key3']
])
values = np.array([
[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.array([10., 20., 30., 40.])
# crunch the numbers
res = np.dot(values, weights)
sortedkeys = keys[res.argsort(axis=0)[::-1]]
答案 2 :(得分:0)
感谢@ondro和@unutbu,以下是我最终的结果:
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()
返回['key3', 'key2', 'key1']
(键,按值和重量的点积按相反的顺序排序)。