我有一個二維陣列,其中列是錦標賽,行是玩家的結果。我想做的是創建結果矩陣,其中每一行代表特定玩家對陣其他人的獲勝頻率。
這是我對這個問題的天真解決方案。
import numpy as np
input_example = np.array([
[55.90, 81.50, 76.60, 69.50],
[52.50, 74.60, 74.00, 64.80],
[52.40, 74.90, 78.20, 60.90],
[52.60, 78.90, 77.60, 60.80],
])
output_example = np.array([
[0.50, 1.00, 0.75, 0.75],
[0.00, 0.50, 0.50, 0.25],
[0.25, 0.50, 0.50, 0.50],
[0.25, 0.75, 0.50, 0.50],
])
def results_matrix(tournament_results):
players, tournaments = tournament_results.shape
res_matrix = np.zeros(shape=(players, tournaments))
for n in range(players):
for m in range(players):
if n == m:
res_matrix[n][m] = 0.50
continue
res_matrix[n][m] = (tournament_results[n] > tournament_results[m]).sum() / tournaments
return res_matrix
if __name__ == '__main__':
res_matrix = results_matrix(input_example)
assert np.array_equal(res_matrix, output_example)
雖然它產生了正確的結果,但我想把它變成慣用的 numpy 解決方案,以便它可以在大輸入下快速作業。
您可以假設特定錦標賽中的結果是不同的,因此沒有任何一對玩家可以有相同的結果。
uj5u.com熱心網友回復:
這個解決方案怎么樣?
players, tournaments = input_example.shape
arr0 = input_example.reshape(players, 1, tournaments)
arr1 = input_example.reshape(1, players, tournaments)
res_matrix = (arr0 > arr1).sum(2)/tournaments
res_matrix[np.arange(players), np.arange(players)] = 0.5
編輯:如果您沒有足夠的記憶體來這樣做,則沒有轉義回圈。但是您可以簡單地使用numba使您的代碼運行得像現在一樣更快。
import numpy as np
from numba import jit
input_example = np.array([
[55.90, 81.50, 76.60, 69.50],
[52.50, 74.60, 74.00, 64.80],
[52.40, 74.90, 78.20, 60.90],
[52.60, 78.90, 77.60, 60.80],
])
output_example = np.array([
[0.50, 1.00, 0.75, 0.75],
[0.00, 0.50, 0.50, 0.25],
[0.25, 0.50, 0.50, 0.50],
[0.25, 0.75, 0.50, 0.50],
])
def results_matrix(tournament_results):
players, tournaments = tournament_results.shape
res_matrix = np.zeros(shape=(players, players))
for n in range(players):
for m in range(players):
if n == m:
res_matrix[n][m] = 0.50
continue
res_matrix[n][m] = (tournament_results[n] > tournament_results[m]).sum() / tournaments
return res_matrix
@jit(nopython=True)
def results_matrix_ba(tournament_results):
players, tournaments = tournament_results.shape
res_matrix = np.zeros(shape=(players, players))
for n in range(players):
for m in range(players):
if n == m:
res_matrix[n][m] = 0.50
continue
res_matrix[n][m] = (tournament_results[n] > tournament_results[m]).sum() / tournaments
return res_matrix
print('running w/o numba')
%timeit assert np.array_equal(output_example, results_matrix(input_example))
print('running with numba')
%timeit assert np.array_equal(output_example, results_matrix_ba(input_example))
輸出:
running w/o numba
The slowest run took 4.10 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 5: 71.9 μs per loop
running with numba
The slowest run took 5.06 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 5: 7.74 μs per loop
np.random.seed(0)
input_example = np.random.rand(900, 500)
print('running w/o numba')
%timeit results_matrix(input_example)
print('running with numba')
%timeit results_matrix_ba(input_example)
輸出:
running w/o numba
1 loop, best of 5: 4.72 s per loop
running with numba
1 loop, best of 5: 407 ms per loop
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/338757.html
上一篇:創建回圈移位陣列的陣列/張量
