8

I have an empty numpy array, and another one populated with values. I want to fill the empty numpy array with the populated one, x times. So, when x = 3, the (originally empty array) would look like [[populated_array],[populated_array], [populated_array]]

Where populated_array is the same value/array each time. I have tried this

a = np.empty(3)
a.fill(np.array([4,6,6,1]))

but get this

ValueError: Input object to FillWithScalar is not a scalar

and want this

[[4,6,6,1],[4,6,6,1],[4,6,6,1]]

cheers for any help.

1
  • You could initialize as object dtype array : a = np.empty(3,dtype=object).
    – Divakar
    Dec 8, 2016 at 18:00

6 Answers 6

Reset to default

Trending sort

Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.

It falls back to sorting by highest score if no posts are trending.

10

tile and repeat are handy functions when you want to repeat an array in various ways:

In [233]: np.tile(np.array([4,6,6,1]),(3,1))
Out[233]: 
array([[4, 6, 6, 1],
       [4, 6, 6, 1],
       [4, 6, 6, 1]])

On the failure, note the docs for fill:

a.fill(value)

Fill the array with a scalar value.

np.array([4,6,6,1]) is not a scalar value. a was initialized as a 3 element float array.

It is possible to assign values to elements of an array, provided the shapes are right:

In [241]: a=np.empty(3)
In [242]: a[:]=np.array([1,2,3])    # 3 numbers into 3 slots
In [243]: a
Out[243]: array([ 1.,  2.,  3.])
In [244]: a=np.empty((3,4))
In [245]: a[:]=np.array([1,2,3,4])   # 4 numbers into 4 columns
In [246]: a
Out[246]: 
array([[ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.]])

This fill works with an object type array, but the result is quite different, and should be used with considerable caution:

In [247]: a=np.empty(3, object)
In [248]: a
Out[248]: array([None, None, None], dtype=object)
In [249]: a.fill(np.array([1,2,3,4]))
In [250]: a
Out[250]: array([array([1, 2, 3, 4]), array([1, 2, 3, 4]), array([1, 2, 3, 4])], dtype=object)

This (3,) array is not the same as the (3,4) array produced by other methods. Each element of the object array is a pointer to the same thing. Changing a value in one element of a changes that value in all the elements (because they are the same object).

In [251]: a[0][3]=5
In [252]: a
Out[252]: array([array([1, 2, 3, 5]), array([1, 2, 3, 5]), array([1, 2, 3, 5])], dtype=object)
2
  • 2
    I thought that there should be a shortcut for this. On the other hand ... It seems silly to provide a shortcut when most of the time you don't need to expand the array if you use broadcasting and indexing tricks effectively ...
    – mgilson
    Dec 8, 2016 at 18:07
  • np.tile might be an old answer to MATLAB repmat. It's a Python function, and makes use of the compiled repeat. With broadcasting it isn't as essential.
    – hpaulj
    Dec 8, 2016 at 18:13
5

Use broadcasting

vstack, tile, and repeat are all great and whatnot, but broadcasting can be several orders of magnitude faster...

import numpy as np
from time import time

t = time()
for _ in xrange(10000):
    a = np.array([4,6,6,1])
    b = np.vstack((a,)*100)
print time()-t

t = time()
for _ in xrange(10000):
    a = np.array([4,6,6,1])
    b = np.tile(a,(3,1))
print time()-t

t = time()
for _ in xrange(10000):
    a = np.array([4,6,6,1])
    b = np.empty([100,a.shape[0]])
    b[:] = a
print time()-t

prints:

2.76399993896
0.140000104904
0.0490000247955
2

You can vstack it:

>>> a = np.array([4,6,6,1])
>>> np.vstack((a,)*3)
array([[4, 6, 6, 1],
       [4, 6, 6, 1],
       [4, 6, 6, 1]])

Note that you frequently don't need to do this... You can do a lot of neat tricks with numpy's broadcasting...:

>>> a = np.array([4,6,6,1])
>>> ones = np.ones((4, 4))
>>> ones * a
array([[ 4.,  6.,  6.,  1.],
       [ 4.,  6.,  6.,  1.],
       [ 4.,  6.,  6.,  1.],
       [ 4.,  6.,  6.,  1.]])

In some cases, you can also use np.newaxis and ... to do neat things as well. It's probably worth looking at numpy's indexing documentation to get familiar with the options.

1

As the Numpy Array Documentation states, first param is shape, son when you're doing:

a = np.empty(3)

You're creating an array of dimension 3 (just one dimension). Instead, you should do:

a = np.empty([3,3])

That creates an array of 3 subarrays of dimension each with dimension 3 (that is a matrix 3x3).

As the Numpy fill Documentation states, fill only takes a number(scalar) as param, so you cannot use another array as argument and what you had done isn't properly working:

a.fill(np.array([4,6,6,1]))

To achieve what you're trying to do, I would do:

a = np.array([[4,6,6,1]]*3)

Hope my comments help you!

0

Repeating tasks like this often get reduced to matrix or vector operations. np.outer() can do it even faster than multiplication with the eye matrix or filling in empty array:

>>>a = np.array([4,6,6,1])
>>>b = np.outer(np.ones(3, dtype=np.int), a)
>>>b
array([[4, 6, 6, 1],
       [4, 6, 6, 1],
       [4, 6, 6, 1]])
0

You could use np.full(), as described here.

>>>repetitions = 3
>>>fill_array = np.array([4,6,6,1])
>>>fill_shape = np.shape(fill_array)
>>>a = np.full([*(repetitions,),*fill_shape],fill_array)
>>>a
array([[4, 6, 6, 1],
       [4, 6, 6, 1],
       [4, 6, 6, 1]])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.