Использование numpy для построения массива всех комбинаций из двух массивов

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

Моя функция принимает значения с плавающей точкой, учитывая, что в качестве входных данных используется массив с 6-точечным числом. Сначала я попытался сделать это:

Сначала я создал функцию, которая принимает 2 массива и генерирует массив со всеми комбинациями значений из двух массивов

from numpy import * def comb(a,b): c = [] for i in a: for j in b: c.append(r_[i,j]) return c 

Затем я применил метод reduce() чтобы применить это к m копиям одного и того же массива:

 def combs(a,m): return reduce(comb,[a]*m) 

И затем я оцениваю свою функцию следующим образом:

 values = combs(np.arange(0,1,0.1),6) for val in values: print F(val) 

Это работает, но это waaaay слишком медленно. Я знаю, что пространство параметров велико, но это не должно быть так медленно. Я использовал только 10 6 (миллионов) баллов в этом примере, и для создания values массива потребовалось больше 15 секунд.

Знаете ли вы более эффективный способ сделать это с помощью numpy?

Я могу изменить способ, которым функция F принимает аргументы, если это необходимо.

  • Есть ли способ получить список имен столбцов в sqlite?
  • Как запустить python для windows?
  • Как обращаться с добавлением элементов и их родителей с помощью xpath
  • Оператор Star (*) применяется к спискам и целям
  • Разделить строку при n-м вхождении заданного символа
  • Учебник Django, Получение: ТипError at / admin / argument для reverse () должен быть последовательностью
  • ReportLab: автоматическое изменение размера текста в соответствии с блоком
  • Вызов Python из Ruby
  • 7 Solutions collect form web for “Использование numpy для построения массива всех комбинаций из двух массивов”

    Вот реализация pure-numpy. Это ок. 5 × быстрее, чем использование itertools.

     import numpy as np def cartesian(arrays, out=None): """ Generate a cartesian product of input arrays. Parameters ---------- arrays : list of array-like 1-D arrays to form the cartesian product of. out : ndarray Array to place the cartesian product in. Returns ------- out : ndarray 2-D array of shape (M, len(arrays)) containing cartesian products formed of input arrays. Examples -------- >>> cartesian(([1, 2, 3], [4, 5], [6, 7])) array([[1, 4, 6], [1, 4, 7], [1, 5, 6], [1, 5, 7], [2, 4, 6], [2, 4, 7], [2, 5, 6], [2, 5, 7], [3, 4, 6], [3, 4, 7], [3, 5, 6], [3, 5, 7]]) """ arrays = [np.asarray(x) for x in arrays] dtype = arrays[0].dtype n = np.prod([x.size for x in arrays]) if out is None: out = np.zeros([n, len(arrays)], dtype=dtype) m = n / arrays[0].size out[:,0] = np.repeat(arrays[0], m) if arrays[1:]: cartesian(arrays[1:], out=out[0:m,1:]) for j in xrange(1, arrays[0].size): out[j*m:(j+1)*m,1:] = out[0:m,1:] return out 

    В новой версии numpy (> 1.8.x) np.meshgrid обеспечивает гораздо более быструю реализацию:

    @ pv решение

     In [113]: %timeit cartesian(([1, 2, 3], [4, 5], [6, 7])) 10000 loops, best of 3: 135 µs per loop In [114]: cartesian(([1, 2, 3], [4, 5], [6, 7])) Out[114]: array([[1, 4, 6], [1, 4, 7], [1, 5, 6], [1, 5, 7], [2, 4, 6], [2, 4, 7], [2, 5, 6], [2, 5, 7], [3, 4, 6], [3, 4, 7], [3, 5, 6], [3, 5, 7]]) 

    numpy.meshgrid используется только для 2D, теперь он способен к ND. В этом случае 3D:

     In [115]: %timeit np.array(np.meshgrid([1, 2, 3], [4, 5], [6, 7])).T.reshape(-1,3) 10000 loops, best of 3: 74.1 µs per loop In [116]: np.array(np.meshgrid([1, 2, 3], [4, 5], [6, 7])).T.reshape(-1,3) Out[116]: array([[1, 4, 6], [1, 5, 6], [2, 4, 6], [2, 5, 6], [3, 4, 6], [3, 5, 6], [1, 4, 7], [1, 5, 7], [2, 4, 7], [2, 5, 7], [3, 4, 7], [3, 5, 7]]) 

    Заметим, что порядок конечного результата несколько отличается.

    itertools.combinations – это, как правило, самый быстрый способ получить комбинации из контейнера Python (если вы действительно хотите сочетать, т. е. соглашения БЕЗ повторений и независимо от порядка, это не то, что ваш код, кажется, делает, но я не могу скажите, связано ли это с тем, что ваш код глючит или потому, что вы используете неправильную терминологию).

    Если вам нужно что-то отличное от комбинаций, возможно, другие итераторы в itertools, product или permutations могут служить вам лучше. Например, похоже, что ваш код примерно такой же, как:

     for val in itertools.product(np.arange(0, 1, 0.1), repeat=6): print F(val) 

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

    Следующая реализация numpy должна быть ок. 2x скорость данного ответа:

     def cartesian2(arrays): arrays = [np.asarray(a) for a in arrays] shape = (len(x) for x in arrays) ix = np.indices(shape, dtype=int) ix = ix.reshape(len(arrays), -1).T for n, arr in enumerate(arrays): ix[:, n] = arrays[n][ix[:, n]] return ix 

    Похоже, вы хотите, чтобы сетка оценивала вашу функцию, и в этом случае вы можете использовать numpy.ogrid (open) или numpy.mgrid ( numpy.mgrid out):

     import numpy my_grid = numpy.mgrid[[slice(0,1,0.1)]*6] 

    Вы можете сделать что-то подобное

     import numpy as np def cartesian_coord(*arrays): grid = np.meshgrid(*arrays) coord_list = [entry.ravel() for entry in grid] points = np.vstack(coord_list).T return points a = np.arange(4) # fake data print(cartesian_coord(*6*[a]) 

    который дает

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

    Вот еще один способ, используя чистый NumPy, не рекурсию, отсутствие понимания списков и отсутствие явных для циклов. Это примерно на 20% медленнее, чем исходный ответ, и он основан на np.meshgrid.

     def cartesian(*arrays): mesh = np.meshgrid(*arrays) # standard numpy meshgrid dim = len(mesh) # number of dimensions elements = mesh[0].size # number of elements, any index will do flat = np.concatenate(mesh).ravel() # flatten the whole meshgrid reshape = np.reshape(flat, (dim, elements)).T # reshape and transpose return reshape 

    Например,

     x = np.arange(3) a = cartesian(x, x, x, x, x) print(a) 

    дает

     [[0 0 0 0 0] [0 0 0 0 1] [0 0 0 0 2] ..., [2 2 2 2 0] [2 2 2 2 1] [2 2 2 2 2]] 
    Interesting Posts

    Каков хороший подход к управлению соединением db в приложении Python Google Cloud SQL (GAE)?

    Вставить приложение просмотра документов Google в формате IFRAME

    Что делает цикл for внутри списка в Python?

    Удалите строку NaN из массива X, а также соответствующую строку в Y

    Параллельные асинхронные процессы с Python, Flask и Celery

    Скрипт Python, чтобы проверить, поврежден ли zip-файл

    Как эффективно и систематически перегружать методы класса Python

    Как импортировать модуль, когда в имени модуля есть «-» тире или дефис?

    Интерактивная функция ноутбука IPython: как установить диапазон ползунков

    Ошибки Pygame2Exe, которые я не могу исправить

    Построение графика с помощью Python

    Использование словаря Python в качестве ключа (не вложенного)

    Может ли sklearn случайный лес напрямую обрабатывать категориальные функции?

    Неверные EigenValues ​​/ Vectors с Numpy

    Python: загрузка файла через FTP-сервер

    Python - лучший язык программирования в мире.