4

What is the most efficient way to extend an array with its own values up to a specific size?

import numpy as np

# For this example, lets use an array with 4 items
data = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]]) # 4 items

# I want to extend it to 10 items, here's the expected result would be:
data = np.array([[ 0,  1,  2],
                 [ 3,  4,  5],
                 [ 6,  7,  8],
                 [ 9, 10, 11],
                 [ 0,  1,  2],
                 [ 3,  4,  5],
                 [ 6,  7,  8],
                 [ 9, 10, 11],
                 [ 0,  1,  2],
                 [ 3,  4,  5]])
Fnord
  • 5,365
  • 4
  • 31
  • 48

2 Answers2

3

You can concatenate arrays:

def extend_array(arr, length):
    factor, fraction = divmod(length, len(arr))
    return np.concatenate([arr] * factor + [arr[:fraction]])

>>> extend_array(data, 10)

array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [ 0,  1,  2],
       [ 3,  4,  5]])
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • Quick correction, you want `arr[:fraction]`. Depending on the size of the array, your method can be noticeably faster because the repeated whole *chunks* are intermediately stored as references to the same object. – Reti43 Jan 26 '16 at 03:01
  • awesome! yes the last item should be arr[:fraction] – Fnord Jan 26 '16 at 03:48
  • Corrected. Changed the name and forgot one of them. – Mike Müller Jan 26 '16 at 07:22
2

The most efficient way I can think of is using the itertools module. First create a cycle of each row (infinite iterator) and then fetch as many rows as you need with islice(). The result of this must be a tuple or list, because numpy requires the length of the array to be explicit at construction time.

import itertools as it

def extend_array(arr, length):
    return np.array(tuple(it.islice(it.cycle(arr), length)))

Usage:

>>> data = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]])
>>> extend_array(data, 10)
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [ 0,  1,  2],
       [ 3,  4,  5]])
Community
  • 1
  • 1
Reti43
  • 9,656
  • 3
  • 28
  • 44