0

Это несколько связанно с Numpy: cartesian product of x and y array points into single array of 2D pointsдекартово произведение произвольных-мерных координат в произвольных одномерных массивах

Я ищу сжатую форму, чтобы создать декартово произведение двух массивов с произвольной размерностью.

Примеры:

По аналогии с соответствующей резьбой, я хочу

x = numpy.array([1,2,3]) #ndim 1 
y = numpy.array([4,5]) #ndim 1 
cartesian_product(x,y) == numpy.array([[[1, 4], 
             [2, 4], 
             [3, 4]], 
             [[1, 5], 
             [2, 5], 
             [3, 5]]]) #ndim "2" = ndim x + ndim y 

Полученный массив 2 мерной потому [1, 4], [2, 4], и т.д. являются координатами и, следовательно, не истинное измерение. Чтобы обобщить, лучше было бы написать x/y как [[1], [2], [3]].

выше, равна

numpy.dstack(numpy.meshgrid(x,y)) 

Но я также хочу

x2 = numpy.array([[1,1], [2,2], [3,3]]) #ndim "1", since [1, 1] is a coordinate 
cartesian_product(x2,y) == numpy.array([[[1, 1, 4], 
             [2, 2, 4], 
             [3, 3, 4]], 

             [[1, 1, 5], 
             [2, 2, 5], 
             [3, 3, 5]]]) #ndim 2 = ndim x2 + ndim y 


y2 = numpy.array([[10, 11], [20, 21]]) #ndim 1 
(cartesian_product(x2, y2) == 
numpy.array([[[1, 1, 10, 11], 
       [2, 2, 10, 11], 
       [3, 3, 10, 11]], 

      [[1, 1, 20, 21], 
       [2, 2, 20, 21], 
       [3, 3, 20, 21]]])) #ndim x2 + ndim y2 

x3 = numpy.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) #ndim 2 
(cartesian_product(x3, y) == 
numpy.array([[[[1, 2, 4], [3, 4, 4]], [[5, 6, 4], [7, 8, 4]]], 
      [[[1, 2, 5], [3, 4, 5]], [[5, 6, 5], [7, 8, 5]]]]) #ndim 3 

Чтобы визуализировать то, что я пытаюсь сделать: Как я уже сказал, [[0, 0], [ 0, 1], [1, 1], [1, 0]] следует интерпретировать как 1-мерный список координат, соответствующий строке. Если я затем делаю декартово произведение с [1, 2, 3, 4], я выдавливаю эту линию в направлении z, превращаясь в поверхность (т. Е. Двумерную). Но теперь массив будет, конечно, трехмерным.

Я полагаю, что я могу найти решение, чтобы решить это с помощью циклов, но есть ли способ достичь этого с помощью инструментов numpy/scipy?

+0

Я не понимаю, что вы подразумеваете под «координатами». Массив результатов в вашем первом примере является трехмерным. Если вы введете его в numpy, у него будет ndim 3. Аналогично, все ваши примеры x2, y2, x3 имеют больше размеров, чем вы думаете. – BrenBarn

+0

Конечно, [[1, 1], [2, 2]] является двумерным массивом. Но в декартовой функции продукта, которую я ищу, она по существу одномерна, так как это всего лишь список координат [coord1, coord2]. [[coord11], coord12], [coord21] [2], будет 2-мерным, хотя его массив равен 2 + 1-мерным. Это может быть проще, если я попытаюсь проиллюстрировать свою проблему, допустим, у меня есть кривая, определенная в xy, это будет список координат, но линия по существу одномерна. То, что я пытаюсь сделать, затем вытесняет его в другом измерении. – mueslo

ответ

1

Память эффективный способ транслируется задание:

def cartesian_product(x, y): 
    if x.ndim < 2: 
     x = np.atleast_2d(x).T 
    if y.ndim < 2: 
     y = np.atleast_2d(y).T 

    sx, sy = x.shape, y.shape 
    sz = sy[:-1] + sx[:-1] + (sy[-1] + sx[-1],) 
    z = np.empty(sz, np.result_type(x, y)) 

    # Broadcasted assignment 
    z[...,:sx[-1]] = x 
    z[...,sx[-1]:] = y.reshape(sy[:-1] + (x.ndim-1)*(1,) + (sy[-1],)) 

    return z 

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