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?

2
  • 4
    What may be a more efficient approach is to allocate some large array, and double the size of it every time you reach capacity. Commented Apr 24, 2013 at 1:09
  • What is the rule that tells you the values to put into the array? What is the rule that tells you what the size of the final array will be, as you are getting the data? This question doesn't appear to describe an adequately clear problem statement. Commented Sep 19, 2023 at 22:09

7 Answers 7

129

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)
Sign up to request clarification or add additional context in comments.

1 Comment

Or better still: a = np.array([x for x in y]); or just a = np.array(list(y))
19

You can do this:

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

4 Comments

That takes linear time per append.
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.
Code should be readable, not fast, unless speed is your bottleneck. Why optimize code you'll run once?
Nice comment @AlexGaudio . I really didn't know that. Thank you!
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

Comments

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)

4 Comments

I made a change here: list(_) and that worked great
To be clear @javadba, you don't need to do that--I'm sure there's some Pythonistas who would take offense :)
This is not a matter of style. without the list(_) it does not even work at last for the case i have that y is an array itself
The OP says "which would result in a containing all the elements of x", so you def do need to do list(_)
1
a = np.empty(0)
for x in y:
    a = np.append(a, x)

1 Comment

This won't work when x has a non-scalar dimension. For example, if x = np.ones((3,5)), it will fail.
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)

Comments

-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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.