Все возможные комбинации 2D numpy массива - PullRequest
2 голосов
/ 03 апреля 2020

У меня есть четыре numpy массива, и пример приведен ниже:

a1=np.array([[-24.4925, 295.77  ],
             [-24.4925, 295.77  ],
             [-14.3925, 295.77  ],
             [-16.4125, 295.77  ],
             [-43.6825, 295.77  ],
             [-22.4725, 295.77  ]])

a2=np.array([[-26.0075, 309.39  ],
             [-24.9975, 309.39  ],
             [-14.8975, 309.39  ],
             [-17.9275, 309.39  ],
             [-46.2075, 309.39  ],
             [-23.9875, 309.39  ]])

a3=np.array([[-25.5025, 310.265 ],
             [-25.5025, 310.265 ],
             [-15.4025, 310.265 ],
             [-17.4225, 310.265 ],
             [-45.7025, 310.265 ],
             [-24.4925, 310.265 ]])

a4=np.array([[-27.0175, 326.895 ],
             [-27.0175, 326.895 ],
             [-15.9075, 326.895 ],
             [-18.9375, 326.895 ],
             [-48.2275, 326.895 ],
             [-24.9975, 326.895 ]])

Я хочу сделать все возможные комбинации между массивами и одновременно объединить, например:

array[-24.4925, 295.77, -26.0075, 309.39, -25.5025, 310.265, -27.0175, 326.895]

и

array[-24.4925, 295.77, -26.0075, 309.39, -25.5025, 310.265, -27.0175, 326.895]

, то есть [a1[0],a2[0],a3[0],a4[0]], [a1[0],a2[0],a3[0],a4[1]] и т. Д.

Какой самый быстрый способ для него, кроме l oop, для четырех массивов? !

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

Ну, нет более быстрого способа, чем зацикливание, но есть чистый способ, при котором вам не нужно писать циклы:

import numpy as np
import itertools

a1=np.array([[-24.4925, 295.77  ],
             [-24.4925, 295.77  ],
             [-14.3925, 295.77  ],
             [-16.4125, 295.77  ],
             [-43.6825, 295.77  ],
             [-22.4725, 295.77  ]])

a2=np.array([[-26.0075, 309.39  ],
             [-24.9975, 309.39  ],
             [-14.8975, 309.39  ],
             [-17.9275, 309.39  ],
             [-46.2075, 309.39  ],
             [-23.9875, 309.39  ]])

a3=np.array([[-25.5025, 310.265 ],
             [-25.5025, 310.265 ],
             [-15.4025, 310.265 ],
             [-17.4225, 310.265 ],
             [-45.7025, 310.265 ],
             [-24.4925, 310.265 ]])

a4=np.array([[-27.0175, 326.895 ],
             [-27.0175, 326.895 ],
             [-15.9075, 326.895 ],
             [-18.9375, 326.895 ],
             [-48.2275, 326.895 ],
             [-24.9975, 326.895 ]])

arrays = [a1, a2, a3, a4]

for pieces in itertools.product(*arrays):
    combined = np.concatenate(pieces, axis = 0)
    print(combined)

Стандартная библиотека itertools module (https://docs.python.org/3/library/itertools.html) предоставляет множество инструментов для производства продуктов, комбинаций, перестановок и т. Д. c. из итераций. Поскольку массив numpy оказывается итеративным (повторяется по первому индексу), мы можем использовать itertools для выделения фрагментов из каждого массива и затем использовать numpy для их объединения.

1 голос
/ 03 апреля 2020

Вот решение numpy, основанное на декартовой реализации продукта из здесь .

arr = np.stack([a1, a2, a3, a4])

print(arr.shape) # (4, 6, 2)
n, m, k = arr.shape

# from https://stackoverflow.com/questions/11144513/cartesian-product-of-x-and-y-array-points-into-single-array-of-2d-points
def cartesian_product(*arrays):
    la = len(arrays)
    dtype = np.result_type(*arrays)
    arr = np.empty([len(a) for a in arrays] + [la], dtype=dtype)
    for i, a in enumerate(np.ix_(*arrays)):
        arr[...,i] = a
    return arr.reshape(-1, la)

inds = cartesian_product(*([np.arange(m)] * n))
res = np.take_along_axis(arr, inds.T[...,None], 1).swapaxes(0,1).reshape(-1, n*k)

print(res[0])
# [-24.4925 295.77   -26.0075 309.39   -25.5025 310.265  -27.0175 326.895 ]

В этом примере массив inds выглядит следующим образом:

print(inds[:10])
# [[0 0 0 0]
#  [0 0 0 1]
#  [0 0 0 2]
#  [0 0 0 3]
#  [0 0 0 4]
#  [0 0 0 5]
#  [0 0 1 0]
#  [0 0 1 1]
#  [0 0 1 2]
#  [0 0 1 3]]

Затем мы можем использовать np.take_along_axis, чтобы выбрать соответствующие элементы для каждой комбинации.

...