Pythonic способ расчета парных точек в списке - PullRequest
0 голосов
/ 25 октября 2018

У меня есть список, который состоит из всех комбинаций кортежей, каждый элемент может быть только -1 или 1. Список может быть сгенерирован как:

N=2
list0 = [p for p in itertools.product([-1, 1], repeat=N)]

Например, если кортеж имеет N=2 элементы:

list0 = [(-1, -1), (-1, 1), (1, -1), (1, 1)]

Таким образом, общее количество кортежей равно 2^2=4.

Если кортеж содержит N=3 элементов:

list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]

Вот мое беспокойство:

Теперь я хотел бы получить все результаты точечных продуктов между любымипара кортежей в списке (в том числе и кортеж с самим собой).Так что для N=2 будет 6(pairs) + 4(itself) = 10 combinations; для N=3 будет 28(pairs) + 8(itself) = 36 combinations.

Для маленьких N Я могу сделать что-то вроде:

for x in list0:
    for y in list0:
        print(np.dot(x,y)) 

Однако, предполагаяУ меня уже есть list0, каков оптимальный способ вычислить все возможности точечных произведений, если N велико, например, ~ 50?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы можете использовать сам np.dot:

import numpy as np

list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]

# approach using np.dot
a = np.array(list0)
result = np.dot(a, a.T)

# brute force approach
brute = []
for x in list0:
    brute.append([np.dot(x, y) for y in list0])
brute = np.array(brute)

print((brute == result).all())

Выход

True

То, что вы спрашиваете, это умножение матрицы a наСамо из документации 1012 *:

, если и a, и b являются двумерными массивами, это умножение матриц,

Обратите внимание, что большинство pythonic разрешается использовать оператор @:

import numpy as np

list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]

# approach using np.dot
a = np.array(list0)
result = a @ a.T

# brute force approach
brute = []
for x in list0:
    brute.append([np.dot(x, y) for y in list0])
brute = np.array(brute)

print((brute == result).all())

Выход

True

Примечание: Код был запущен в Python 3.5

0 голосов
/ 25 октября 2018

Вы можете придерживаться NumPy

import numpy as np
import random


vals = []
num_vecs = 3
dimension = 4
for n in range(num_vecs):
    val = []
    for _ in range(dimension):
        val.append(random.random())
    vals.append(val)

# make into numpy array
vals = np.stack(vals)
print(vals.shape == (num_vecs, dimension))

# multiply every vector with every other using broadcastin
every_with_every_mult = vals[:, None] * vals[None, :]
print(every_with_every_mult.shape == (num_vecs, num_vecs, dimension))

# sum the final dimension
every_with_every_dot = np.sum(every_with_every_mult, axis=every_with_every_mult.ndim - 1)
print(every_with_every_dot.shape == (num_vecs, num_vecs))

# check it works
for i in range(num_vecs):
    for j in range(num_vecs):
        assert every_with_every_dot[i,j] == np.sum(vals[i]*vals[j])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...