2

I have an array of values and would like to create a matrix from that, where each row is my starting point vector multiplied by a sample from a (normal) distribution. The number of rows of this matrix will then vary in dependence from the number of samples I want.

%pylab
my_vec = array([1,2,3])
my_rand_vec = my_vec*randn(100)

Last command does not work, because array shapes do not match. I could think of using a for loop, but I am trying to leverage on array operations.

Michele Ancis
  • 1,265
  • 4
  • 16
  • 29

3 Answers3

3

Try this

my_rand_vec = my_vec[None,:]*randn(100)[:,None]

For small numbers I get for example

import numpy as np
my_vec = np.array([1,2,3])
my_rand_vec = my_vec[None,:]*np.random.randn(5)[:,None]
my_rand_vec

# array([[ 0.45422416,  0.90844831,  1.36267247],
#        [-0.80639766, -1.61279531, -2.41919297],
#        [ 0.34203295,  0.6840659 ,  1.02609885],
#        [-0.55246431, -1.10492863, -1.65739294],
#        [-0.83023829, -1.66047658, -2.49071486]])

Your solution my_vec*rand(100) does not work because * corresponds to the element-wise multiplication which only works if both arrays have identical shapes.

What you have to do is adding an additional dimension using [None,:] and [:,None] such that numpy's broadcasting works.

As a side note I would recommend not to use pylab. Instead, use import as in order to include modules as pointed out here.

Community
  • 1
  • 1
plonser
  • 3,323
  • 2
  • 18
  • 22
2

It is the outer product of vectors:

my_rand_vec = numpy.outer(randn(100), my_vec)
eph
  • 1,988
  • 12
  • 25
2

You can pass the dimensions of the array you require to numpy.random.randn:

my_rand_vec = my_vec*np.random.randn(100,3)

To multiply each vector by the same random number, you need to add an extra axis:

my_rand_vec = my_vec*np.random.randn(100)[:,np.newaxis]
xnx
  • 24,509
  • 11
  • 70
  • 109