Создайте генератор со всеми возможными комбинациями в матрице (я не могу хранить весь массив, но я могу только перебирать его) [duplicate]

UPDATE: Действительно умные люди быстро указали на этот ответ , который объясняет странность, описанную ниже

ОРИГИНАЛЬНЫЙ ОТВЕТ:

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

ApplicationContext context =
    new ClassPathXmlApplicationContext(new String[] {
        "common.xml",
        "token.xml",
        "pep-config.xml" });
    TokenInitializer ti = context.getBean(TokenInitializer.class);

и в файле token.xml у меня была строка


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

И после этого NPE начал заходить. В pep-config.xml у меня было всего 2 боба:



и класс SomeAbac имеет свойство, объявленное как

@Autowired private Settings settings;

по неизвестной причине, настройки null в init (), когда элемент отсутствует вообще, но когда он присутствует и имеет некоторые bs в качестве basePackage, все работает Что ж. Теперь эта строка выглядит так:


, и она работает. Может быть, кто-то может дать объяснение, но для меня это достаточно прямо сейчас)

10
задан Christoph 17 January 2011 в 03:20
поделиться

6 ответов

эквивалент NumPy itertools.product() равен numpy.indices(), но он только даст вам произведение диапазонов формы 0, ..., k-1:

numpy.rollaxis(numpy.indices((2, 3, 3)), 0, 4)
array([[[[0, 0, 0],
         [0, 0, 1],
         [0, 0, 2]],

        [[0, 1, 0],
         [0, 1, 1],
         [0, 1, 2]],

        [[0, 2, 0],
         [0, 2, 1],
         [0, 2, 2]]],


       [[[1, 0, 0],
         [1, 0, 1],
         [1, 0, 2]],

        [[1, 1, 0],
         [1, 1, 1],
         [1, 1, 2]],

        [[1, 2, 0],
         [1, 2, 1],
         [1, 2, 2]]]])

. Для вашего в специальном случае вы можете использовать

a = numpy.indices((4,)*13)
b = 1j ** numpy.rollaxis(a, 0, 14)

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

EIDT: просто упомянуть об этом: вызов numpy.rollaxis() более или менее косметический, чтобы получить тот же результат, что и itertools.product(). Если вы не заботитесь о порядке индексов, вы можете просто опустить его (но он все равно дешев, если у вас нет никаких последующих действий, которые преобразуют ваш массив в смежный массив.)

EDIT2: Чтобы получить точный аналог

numpy.array(list(itertools.product(some_list, repeat=some_length)))

, вы можете использовать

numpy.array(some_list)[numpy.rollaxis(
    numpy.indices((len(some_list),) * some_length), 0, some_length + 1)
    .reshape(-1, some_length)]

. Это стало совершенно нечитаемым - просто скажите, нужно ли мне это объяснять далее:)

12
ответ дан Sven Marnach 22 August 2018 в 08:16
поделиться
  • 1
    Хм. Однако мне пришлось бы изменить форму. Но это, вероятно, еще быстрее. Благодаря! Позвольте мне поиграть с этим немного. – Christoph 17 January 2011 в 16:50
  • 2
    @ Кристоф: перестройка дешево, так как она вообще не изменяет данные. – Sven Marnach 17 January 2011 в 16:52
  • 3
    @Christoph: Нет, вызов не является строго необходимым, он только приносит массив в той же форме, что и ваша оригинальная версия. Я не знаю, что вы собираетесь делать с перестановками, поэтому я не могу дать совет, как это сделать. Но я лично не стал бы вообще использовать rollaxis() или reshape(), а использовать выход indices() как есть. Например, вы можете перебирать все перестановки с помощью for perm in izip(*(a.ravel() for a in numpy.indices(...))). Скорее всего, вы также можете обойтись без изменения вашего приложения. – Sven Marnach 17 January 2011 в 17:42
  • 4
    @ Кристоф. Это точно такие же результаты, даже в том же порядке, для чего это стоит. – Joe Kington 17 January 2011 в 17:43
  • 5
    @Christoph: Если a = numpy.indices((4,)*4), то a[0] будет содержать все значения для первого «индекса», a[1] будут значениями для второго «индекса» и т. Д. Для каждого n в диапазоне от 0 до 4 ^ 4-1 a[0].flat[n], a[1].flat[n], a[2].flat[n], a[3].flat[n] будет допустимой перестановкой без дубликатов. Если вас смущает упорядочение результатов, просто используйте rollaxis(), но вам этого не нужно. – Sven Marnach 17 January 2011 в 18:01

Пусть numpy.meshgrid выполняет все задание:

length = 13
x = [1, -1, 1j, -1j]
mesh = numpy.meshgrid(*([x] * length))
result = numpy.vstack([y.flat for y in mesh]).T

на моем ноутбуке требуется ~ 2 минуты

0
ответ дан Alleo 22 August 2018 в 08:16
поделиться

Первая строка кажется мгновенной, поскольку фактическая операция не выполняется. Объект-генератор только что сконструирован и только тогда, когда вы выполняете его через операцию. Как вы сказали, вы получаете номера 4^13 = 67108864, все они вычисляются и становятся доступными во время вашего вызова list. Я вижу, что np.array принимает только список или кортеж, поэтому вы можете попробовать создать кортеж из своего итератора и передать его np.array, чтобы увидеть, есть ли разница в производительности, и это не влияет на общую производительность вашей программы , Это можно определить, только пытаясь использовать ваш файл, хотя есть некоторые точки , которые говорят, что кортеж немного быстрее.

Чтобы попробовать с кортежем, вместо списка просто сделайте

sendbuf = np.array(tuple(c))
5
ответ дан Community 22 August 2018 в 08:16
поделиться
  • 1
    Спасибо, Сентил. Если ничего не работает, я попробую с кортежами. – Christoph 17 January 2011 в 17:35

Возможно, вы захотите попробовать совершенно другой подход: сначала создайте пустой массив желаемого размера:

result = np.empty((4**length, length), dtype=complex)

, затем используйте способности NumPy для нарезки, чтобы заполнить массив самостоятельно:

# Set up of the last "digit":
result[::4, length-1] = 1
result[1::4, length-1] = -1
result[2::4, length-1] = 1j
result[3::4, length-1] = -1j

Вы можете делать подобные вещи для других «цифр» (т. е. элементов результата [:, 2], результата [:, 1] и результата [:, 0]). Все это, безусловно, можно было бы ввести в цикл, который итерации по каждой цифре.

Перенос всей операции (np.empty((length, 4**length)…)) стоит попробовать, так как это может привести к увеличению скорости (благодаря лучшему использованию кеш памяти).

5
ответ дан Eric Lebigot 22 August 2018 в 08:16
поделиться
  • 1
    Еще не проверял, но это было именно то, что я представлял, спасибо! – Christoph 17 January 2011 в 15:41
  • 2
    @Christoph: Я думаю, что NumPy жалуется, потому что fromiter() пытается создать массив 1D tuples (эта функция создает только 1D-массивы). Таким образом, хороший выбор типа был бы dtype=object ... но NumPy отказывается это делать. Я не уверен, как решить эту проблему (кроме лоббирования за возможность использования dtype=object :). – Eric Lebigot 17 January 2011 в 16:19
  • 3
    Ах, облом. Спасибо, в любом случае :) – Christoph 17 January 2011 в 16:30
  • 4
    & Амп; @Christoph - вы можете обойти это, используя структурированный массив, а затем просматривая его как «обычный». массив. Вот как это делается: pastebin.com/tBLkzL64 К сожалению, это не быстрее, чем просто использовать список или кортеж, чтобы сделать это, как вы изначально были. – Joe Kington 17 January 2011 в 16:59
  • 5
    Это, похоже, не дает правильного ответа (даже если вы используете цикл для этого для каждой цифры и). Если бы это было так, это была бы самая быстрая версия до сих пор ... Я понял, что вы означает правильно? Вот как я реализовал эту версию: pastebin.com/VpwXVkQs – Joe Kington 17 January 2011 в 17:36
  • 6
    @Joe: Я имел в виду нечто отличное от вашей реализации, а именно, что перед предыдущими цифрами result[:, length-1] должно быть установлено значение [1, 1, 1, 1, -1, -1, -1, -1, 1j, 1j, и т.д.]. И аналогично для последующих цифр (с повторяющимися последовательностями увеличивающегося размера). Яснее? :) – Eric Lebigot 17 January 2011 в 18:25
  • 7
    @Joe: То, что я предлагал, по сути является тем, что делает numpy.indices(); разница в том, что я устанавливал координаты вручную, но прямо к значениям, запрошенным в вопросе. – Eric Lebigot 21 January 2011 в 10:48
  • 8
    @Joe: Большое спасибо! Это именно то, что я имел в виду. – Eric Lebigot 21 January 2011 в 12:04

Вероятно, не оптимизирован, но гораздо меньше зависит от преобразований типа python:

ints = [1,2,3,4]
repeat = 3

def prod(ints, repeat):
    w = repeat
    l = len(ints)
    h = l**repeat
    ints = np.array(ints)
    A = np.empty((h,w), dtype=int)
    rng = np.arange(h)
    for i in range(w):
        x = l**i
        idx = np.mod(rng,l*x)/x
        A[:,i] = ints[idx]
    return A   
1
ответ дан Paul 22 August 2018 в 08:16
поделиться
5
ответ дан Eric Lebigot 5 November 2018 в 05:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: