Как математически работает функция numpy `array_split`? - PullRequest
0 голосов
/ 07 ноября 2019

Мне нужно написать функцию Python, которая при передаче массива и целого числа N возвращает содержимое массива, разделенного на N подмассивов одинакового размера.

Если длина массива не можетделится поровну на N, конечные подмассивы должны иметь подходящую длину для размещения оставшихся элементов.

Пример: split_array(array=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], n=4)

Должно выдать: [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10]]

Мое исследование показало, что функция numpy.array_split делает именно это, и я посмотрел на исходный код GitHub и обнаружил, что сначала он создает массив, содержащий все размеры вложенного элемента. массивы, которые затем перебираются для разделения исходного массива.

Сокращенный образец из numpy.array_split

def array_split(ary, indices_or_sections, axis=0):
    # indices_or_sections is a scalar, not an array.
    Nsections = int(indices_or_sections)
    if Nsections <= 0:
        raise ValueError('number sections must be larger than 0.')
    Neach_section, extras = divmod(Ntotal, Nsections)
    section_sizes = ([0] +
                     extras * [Neach_section+1] +
                     (Nsections-extras) * [Neach_section])
    div_points = _nx.array(section_sizes, dtype=_nx.intp).cumsum()

    sub_arys = []
    sary = _nx.swapaxes(ary, axis, 0)
    for i in range(Nsections):
        st = div_points[i]
        end = div_points[i + 1]
        sub_arys.append(_nx.swapaxes(sary[st:end], axis, 0))

    return sub_arys

Единственное, что я изо всех сил пытаюсь понять, это какпеременная section_sizes создается математически. Для примера split_array(array=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], n=4) он создает список размеров, который будет [3, 3, 2, 2], и это именно то, что мне нужно, но я не понимаю, почему это работает.

Я понимаю, что divmod(Ntotal, Nsections) даст вам частное (Neach_section) и остаток (extras) вычисления деления.

Но почему quotient * [remainder+1] всегда дает точное количество правильных размеров «частных» размеров подмассива (В случае этого примера [3, 3])?

Почему [quotient-remainder] * quotient дает вам точное правильное количество правильных размеров «остаточных» размеров подмассива (В случае этого примера [2, 2])?

Может кто-тодаже просто скажите мне, как называется эта операция или с какой областью математики это связано, поскольку я не сталкивался с этим раньше.

1 Ответ

1 голос
/ 08 ноября 2019

Для ясности я буду ссылаться на это:

Neach_section, extras = divmod(Ntotal, Nsections)
section_sizes = ([0] +
                 extras * [Neach_section+1] +
                 (Nsections-extras) * [Neach_section])

как

quotient, remainder = divmod(Ntotal, Nsections)
section_sizes = ([0] +
                 remainder * [quotient+1] +
                 (Nsections- remainder) * [quotient])

Сначала давайте представим случай, аналогичный показанному в вашем вопросе. (Изменено для фактора! = Остаток)

print(np.array_split(np.arange(1,15),4) 
>>>[array([1, 2, 3, 4]), array([5, 6, 7, 8]), array([ 9, 10, 11]), array([12, 13, 14])]

Проще представить его с точки зрения разделения, которое это в конечном итоге представляет.

14 = 4 * 3 + 2

Что также соответствует

14 = (3 + 3 + 3 + 3) + 2

= (3 + 3 + 3 + 3) + (1 + 1)

И, что очень важно, мы можем добавить их к первым двум слагаемым в первой скобке.

14 = 4 + 4+ 3 + 3

В общем, мы добавили один к первому (остаточному) условию списка вывода, оставив нам фрагмент кода

...remainder * [quotient+1]...

Из (частных) терминов в выходных данных мы добавили первые (оставшиеся) термины, оставляя нас со следующими (частными) остатками, чтобы заполнить

...(Nsections- remainder) * [quotient])

Оставив нам окончательный код.

Может ли кто-нибудь даже сказать мне, как называется этот тип операции или с какой областью математики это имеет дело, поскольку я не сталкивался с этим раньше.

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

В любом случае, я надеюсь, что это помогло:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...