Создайте массив массивов numpy с ведущими нулями и разными начальными и конечными точками

У меня разные целые начальные и конечные значения, и мне нужны все целые значения между ними в виде массивов в одном массиве формы (theRange, finalLength).

Пример:

finalLength = 6
start = 2
stop = 3456
theRange = (stop - start) + 1


>>> array([[0, 0, 0, 0, 0, 2],
           [0, 0, 0, 0, 0, 3],
           [0, 0, 0, 0, 0, 4],
           ...,
           [0, 0, 3, 4, 5, 4],
           [0, 0, 3, 4, 5, 5],
           [0, 0, 3, 4, 5, 6]])

>>> array.shape (3455, 6)

Поскольку мне нужно запускать эту функцию миллиарды раз, текущий способ — замедление.

На данный момент я создаю нужный диапазон, используя np.linspace. Целые числа разбиваются на цифры следующим образом (Разбить целое число на цифры с помощью numpy.

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

Время увеличивается с увеличением finalLength: Timeit 10000 повторений

finalLength = 6 --› время: 2,815263898999546

finalLength = 12 --› время: 4.158567378000043

finalLength = 24 --› время: 5.038266787999419

Есть ли более быстрый способ создать окончательный массив?

Воспроизводимый код:

import numpy as np

finalLength = 6
start = 2
stop = 3456
theRange = (stop - start) + 1

def makeRangeArray(start, stop, theRange, finalLength):
    # create integers within range
    ll = np.array(np.linspace(start=start, stop=stop, num=theRange), dtype=np.int64)

    # split integers into arrays
    b = 10
    n = np.ceil(np.max(np.log(ll) / np.log(b))).astype(np.int64)
    d = np.arange(n)
    d.shape = d.shape + (1,) * ll.ndim
    out = ll // b ** d % b

    # add leading zeros if necessary
    if finalLength - out.shape[0] != 0:
        addZeros = np.zeros([finalLength - out.shape[0], out.shape[1]], dtype=np.int64)
        out = np.append(out, addZeros, axis=0)  # insert zeros at the end of array

    # flip
    out = np.flip(out, axis=0)

    # transpose to desired final output format
    aaa = out.transpose().reshape((theRange, finalLength))

    return aaa

person arminf82    schedule 26.02.2020    source источник
comment
Поскольку мне нужно запускать эту функцию миллиарды раз, текущий способ - замедлить. Я думаю, вам лучше всего найти способ не запускать что-либо миллиарды раз, предполагая, что мы говорим относительно короткий промежуток времени, конечно.   -  person AMC    schedule 27.02.2020
comment
Чтобы добавить к комментарию AMC, если один и тот же массив используется каждый раз, сгенерируйте один раз и используйте его как глобальную переменную или передайте массив между функциями. Если вам нужны предложения по оптимизации вашего рабочего процесса, вы можете открыть еще один вопрос.   -  person Michael    schedule 27.02.2020
comment
Я хочу создать все возможные комбинации чисел для определенной длины слова, например. 16-значные числа с кодировкой 0-9 дадут 10 000 000 000 000 000 возможных комбинаций. Чтобы использовать np.unique() для фильтрации целевых комбинаций, например. отбросить все комбинации, имеющие более 8 повторяющихся цифр, мне нужно число как массивы. Из-за ограничений памяти и процессора я хочу работать с фрагментами данных. Следовательно, работа с таким количеством комбинаций для фильтрации приведет к миллиардам фрагментов. Я пробую разные подходы, но до сих пор не мог найти достаточно быстрый способ.   -  person arminf82    schedule 01.03.2020