Создание декартова произведения набора векторов в Python?

Учитывая стандартные базисные векторы (e_1,e_2,e_3) в 3 измерениях и позволяя элементам (e_1,e_2,e_3) ограничиваться, скажем, (0,1,2,3,4), существует ли простой питонический способ создать декартово произведение всех векторов в этом векторном пространстве?

Например, учитывая [1,0,0],[0,1,0] и [0,0,1], я хотел бы получить список всех линейных комбинаций (где a_i ограничены натуральными числами между 0 и 4) этих векторов между [0,0,0] и [4,4,4].

Я мог бы запрограммировать это сам, но прежде чем приступить к этой проблеме, я решил спросить, есть ли простой питонический способ сделать это, может быть, в numpy или чем-то подобном.


person sfortney    schedule 19.05.2015    source источник
comment
Лучший способ — пойти [...] на эту проблему и чему-нибудь научиться. Если у вас возникнут какие-либо проблемы, возвращайтесь. Если вы решили свою проблему, то все в порядке. Если вас это не устраивает, перейдите на codereview.stackexchange.com.   -  person tamasgal    schedule 19.05.2015
comment
@septi Спасибо за ответ, но я также хотел посмотреть, есть ли какие-либо встроенные функции, которые делают это. Я считаю, что полезно поспрашивать и получить идеи, прежде чем пытаться сделать что-то, что мне кажется чем-то вроде изобретения велосипеда. Кроме того, поскольку это кажется мне довольно распространенным явлением, я думаю, что это может помочь будущим другим, которые могут наткнуться на это. Я думаю, что это совершенно правильный вопрос. Извините, если вы так не думаете.   -  person sfortney    schedule 19.05.2015
comment
Я почти уверен, что нет готовой к использованию функции для этой конкретной проблемы. Однако, как вы выяснили, есть itertools, а numpy отлично подходит для векторов и матриц. Так что научитесь их использовать, и я уверен, что вы найдете хорошее решение.   -  person tamasgal    schedule 19.05.2015
comment
Похоже, вы просто хотите itertools.product((0,1,2,3,4), repeat=3). Вы описываете декартово произведение, а не мощность.   -  person Eric    schedule 19.05.2015
comment
Ты прав. Хотя эти два понятия похожи, декартово произведение является математически правильным определением. И ваш ответ - отличный способ сделать это. Теперь, когда вы говорите, что это может быть помечено как дубликат stackoverflow.com/questions/533905/   -  person sfortney    schedule 19.05.2015
comment
Ближе к stackoverflow.com/q/1208118/102441 я думаю, поскольку различие numpy важно   -  person Eric    schedule 19.05.2015


Ответы (2)


Для конкретного случая пространства натуральных чисел вам нужно np.indices:

>>> np.indices((4, 4)).reshape(2,-1).T
array([[0, 0],
       [0, 1],
       [0, 2],
       [0, 3],
       [1, 0],
       [1, 1],
       [1, 2],
       [1, 3],
       [2, 0],
       [2, 1],
       [2, 2],
       [2, 3],
       [3, 0],
       [3, 1],
       [3, 2],
       [3, 3]])

(на самом деле numpy выводит их в сетке, но вам нужен одномерный список точек, поэтому .reshape)

В противном случае то, что вы описываете, это не набор мощности, а декартово произведение.

itertools.product(range(4), repeat=3)
person Eric    schedule 19.05.2015

Изменить: этот ответ работает, но я думаю, что ответ Эрика лучше, потому что его легче обобщить.

В интересах помощи другим, которые могут наткнуться на этот вопрос. Вот очень простой способ ответить на вышеуказанный вопрос. Он использует np.where, чтобы найти все индексы матрицы, соответствующие определенным критериям. Здесь нашим критерием является как раз то, чему удовлетворяет вся матрица. Это эквивалентно проблеме выше. Это верно только для примера, как указано выше, но не должно быть слишком сложно обобщить это до N измерений.

import numpy as np
dim=3
gran=5

def vec_powerset(dim, gran):
    #returns a list of all the vectors for a three dimensional vector space
    #where the elements of the vectors are the naturals up to gran

    size=tuple([gran]*dim)
    a=np.zeros(size)

    return [[np.where(a>(-np.inf))[0][x],np.where(a>(-np.inf))[1][x],
    np.where(a>(-np.inf))[2][x]] for x in
    range(len(np.where(a>(-np.inf))[0]))]

print vec_powerset(dim,gran)

[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 2, 3], [0, 2, 4], [0, 3, 0], [0, 3, 1], [0, 3, 2], [0, 3, 3], [0, 3, 4], [0, 4, 0], [0, 4, 1], [0, 4, 2], [0, 4, 3], [0, 4, 4], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 0, 3], [1, 0, 4], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 3, 0], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 4, 0], [1, 4, 1], [1, 4, 2], [1, 4, 3], [1, 4, 4], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 0, 3], [2, 0, 4], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 1, 4], [2, 2, 0], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 3, 0], [2, 3, 1], [2, 3, 2], [2, 3, 3], [2, 3, 4], [2, 4, 0], [2, 4, 1], [2, 4, 2], [2, 4, 3], [2, 4, 4], [3, 0, 0], [3, 0, 1], [3, 0, 2], [3, 0, 3], [3, 0, 4], [3, 1, 0], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 1, 4], [3, 2, 0], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 2, 4], [3, 3, 0], [3, 3, 1], [3, 3, 2], [3, 3, 3], [3, 3, 4], [3, 4, 0], [3, 4, 1], [3, 4, 2], [3, 4, 3], [3, 4, 4], [4, 0, 0], [4, 0, 1], [4, 0, 2], [4, 0, 3], [4, 0, 4], [4, 1, 0], [4, 1, 1], [4, 1, 2], [4, 1, 3], [4, 1, 4], [4, 2, 0], [4, 2, 1], [4, 2, 2], [4, 2, 3], [4, 2, 4], [4, 3, 0], [4, 3, 1], [4, 3, 2], [4, 3, 3], [4, 3, 4], [4, 4, 0], [4, 4, 1], [4, 4, 2], [4, 4, 3], [4, 4, 4]]
person sfortney    schedule 19.05.2015
comment
Вам нужно перестать использовать термин powerset для этого. Это привлекает неправильные результаты поиска. - person Dzamo Norton; 11.08.2016
comment
Я с удовольствием отредактирую, если вы дадите мне лучший термин. Я знаю, что это неправильно, но я не мог придумать лучшего способа сказать это. А пока я взял название в кавычки - person sfortney; 11.08.2016
comment
Вы формируете декартово произведение. en.wikipedia.org/wiki/Cartesian_product - person Dzamo Norton; 12.08.2016