77

I want to be able to 'build' a numpy array on the fly, I do not know the size of this array in advance.

For example I want to do something like this:

a= np.array()
for x in y:
     a.append(x)

Which would result in a containing all the elements of x, obviously this is a trivial answer. I am just curious whether this is possible?

user1220022
  • 11,167
  • 19
  • 41
  • 57
  • 3
    What may be a more efficient approach is to allocate some large array, and double the size of it every time you reach capacity. – wim Apr 24 '13 at 01:09

7 Answers7

126

Build a Python list and convert that to a Numpy array. That takes amortized O(1) time per append + O(n) for the conversion to array, for a total of O(n).

    a = []
    for x in y:
        a.append(x)
    a = np.array(a)
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 3
    Or better still: `a = np.array([x for x in y])`; or just `a = np.array(list(y))` – A T Jan 19 '18 at 23:58
19

You can do this:

a = np.array([])
for x in y:
    a = np.append(a, x)
alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • 6
    That takes linear time per append. – Fred Foo Apr 12 '12 at 11:02
  • 13
    This approach copies the array every append, which is O(sum(range(n))). On my laptop, this method was 42 times slower than @larsman's method: Building a list following larsmans method exactly takes me 1000 loops, best of 3: 1.53 ms per loop . Following this method exactly takes me 10 loops, best of 3: 64.8 ms per loop. – Alex Gaudio Feb 14 '13 at 21:59
  • 1
    Code should be readable, not fast, unless speed is your bottleneck. Why optimize code you'll run once? – Marcos Pereira May 20 '20 at 08:01
  • Nice comment @AlexGaudio . I really didn't know that. Thank you! – Prasad Raghavendra Jun 20 '20 at 14:55
7

Since y is an iterable I really do not see why the calls to append:

a = np.array(list(y))

will do and it's much faster:

import timeit

print timeit.timeit('list(s)', 's=set(x for x in xrange(1000))')
# 23.952975494633154

print timeit.timeit("""li=[]
for x in s: li.append(x)""", 's=set(x for x in xrange(1000))')
# 189.3826994248866
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
1

For posterity, I think this is quicker:

a = np.array([np.array(list()) for _ in y])

You might even be able to pass in a generator (i.e. [] -> ()), in which case the inner list is never fully stored in memory.


Responding to comment below:

>>> import numpy as np
>>> y = range(10)
>>> a = np.array([np.array(list) for _ in y])
>>> a
array([array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object),
       array(<type 'list'>, dtype=object)], dtype=object)
BenDundee
  • 4,389
  • 3
  • 28
  • 34
1
a = np.empty(0)
for x in y:
    a = np.append(a, x)
chiefenne
  • 565
  • 2
  • 15
  • 30
0

I wrote a small utility function. (most answers above are good. I feel this looks nicer)

def np_unknown_cat(acc, arr):
  arrE = np.expand_dims(arr, axis=0)
  if acc is None:
    return arrE
  else:
    return np.concatenate((acc, arrE))

You can use the above function as the following:

acc = None  # accumulator
arr1 = np.ones((3,4))
acc = np_unknown_cat(acc, arr1)
arr2 = np.ones((3,4))
acc = np_unknown_cat(acc, arr2)
Shubham Agrawal
  • 182
  • 2
  • 12
-1
list1 = []
size = 1
option = "Y"
for x in range(size):
    ele = input("Enter Element For List One : ")
    list1.append(ele)
while(option == "Y"):
    option = input("\n***Add More Element Press Y ***: ")
    if(option=="Y"):
        size = size + 1
        for x in range(size):
            ele = input("Enter Element For List Element : ")
            list1.append(ele)
            size = 1
    else:
        break;
print(list1)

Take:

list1 = []    # Store Array Element 
size = 1      # Rune at One Time 
option = "Y"  # Take User Choice 

Implementation:

  • For Loop at a range of size variable which runs one time because size = 1
  • use While loop
    • take input from users if they want to add press "Y" else "N"
    • in the while loop use the if else statement if the option is "Y" then increase size with which helps run 2 time array because size = size + 1 run another for loop at a range of size
    • else break