Самый быстрый способ создания матрицы парного сопоставления из одного массива numpy

#python #arrays #numpy #permutation

#python #массивы #numpy #перестановка

Вопрос:

Я хочу выполнить быстрые парные сопоставления всех элементов в массиве numpy, игнорируя самосогласование.

Например, учитывая массив numpy, такой как

 a = np.array(range(4))
 

Я хочу получить матрицу, подобную

 array([[0, 1], 
       [0, 2],
       [0, 3],
       [1, 0],
       [1, 2],
       [1, 3],
       [2, 0],
       [2, 1],
       [2, 3],
       [3, 0],
       [3, 1],
       [3, 2]])
 

В моем реальном случае у меня разные размеры массивов, варьирующиеся от 1 до 1000. Мне нужно постоянно вызывать функцию, которая выполняет это парное сопоставление. Я написал код ниже

 import numpy as np
from itertools import permutations

a = np.array(range(1000))
xs, ys = zip(*[(x, y) for x, y in permutations(a, 2)])
res = np.vstack([np.array(xs), np.array(ys)]).T
print(res)
 

Я хочу знать, есть ли более быстрые способы (возможно, более простые способы) для этого?

Я хотел бы увидеть некоторые сравнительные показатели времени выполнения и размера массива.

Комментарии:

1. Не уверен, есть ли способ numpic, но как насчет — np.array(list(permutations(a,2)))

Ответ №1:

Создание сетки с последующей фильтрацией «совпадающих» строк (например 0,0 , и 12,12 ), вероятно, будет немного быстрее в этом масштабе.

 import numpy as np
from itertools import permutations

%%time
n = 1000
a = np.array(np.arange(n))
xs, ys = zip(*[(x, y) for x, y in permutations(a, 2)])
res = np.vstack([np.array(xs), np.array(ys)]).T
res
CPU times: user 1.08 s, sys: 176 ms, total: 1.26 s
Wall time: 1.28 s
 
 %%time
n = 1000
a = np.arange(n)
arr = np.array(np.meshgrid(a, a)).T.reshape(-1,2)
arr = arr[arr[:, 0] != arr[:, 1]]
CPU times: user 49.8 ms, sys: 33.2 ms, total: 83 ms
Wall time: 89.2 ms
 
 %%time
n = 2000
a = np.array(np.arange(n))
xs, ys = zip(*[(x, y) for x, y in permutations(a, 2)])
res = np.vstack([np.array(xs), np.array(ys)]).T
res
CPU times: user 3.94 s, sys: 924 ms, total: 4.86 s
Wall time: 5.03 s
 
 %%time
n = 2000
a = np.arange(n)
arr = np.array(np.meshgrid(a, a)).T.reshape(-1,2)
arr = arr[arr[:, 0] != arr[:, 1]]
CPU times: user 218 ms, sys: 105 ms, total: 323 ms
Wall time: 328 ms
 
 np.testing.assert_array_equal(res, arr) # passes